逐步解說:呼叫 Windows API (Visual Basic)

Windows API 是屬於 Windows 作業系統一部分的動態連結程式庫 (DLL)。 當您難以撰寫自己的相等程式時,可以使用這些程式來執行工作。 例如,Windows 提供名為 FlashWindowEx 的函式,可讓您將應用程式的標題列在淺色和深色之間切換。

在您的程式碼中使用 Windows API 的優點是可以節省開發時間,因為其中包含數十個預先撰寫且可直接使用的實用函式。 缺點是 Windows API 可能不易運用,且在發生問題時無法解決。

Windows API 提供一種特殊的互通性。 Windows API 不使用受控程式碼、沒有內建類型程式庫,並使用與 Visual Studio 不同的資料類型。 由於這些差異,加上 Windows API 不是 COM 物件,因此與 Windows API 以及 .NET Framework 的互通性是使用平台叫用或 PInvoke 來執行。 平台叫用服務,可讓受控程式碼呼叫非受控函式在 DLL 中實作。 如需詳細資訊,請參閱使用非受控 DLL 函式。 您可以在 Visual Basic 中使用 PInvoke,方法是使用 Declare 陳述式或將 DllImport 屬性套用至空白程序。

Windows API 呼叫在過去是 Visual Basic 程式設計的重要部分,但 Visual Basic .NET 則很少需要用。 在情況允許時,您應該使用 .NET Framework 中的受控程式碼來執行工作,而不是 Windows API 呼叫。 本逐步解說提供需要使用 Windows API 的情境資訊。

注意

在下列指示的某些 Visual Studio 使用者介面項目中,您的電腦可能會顯示不同的名稱或位置: 您所擁有的 Visual Studio 版本以及使用的設定會決定這些項目。 如需詳細資訊,請參閱將 Visual Studio IDE 個人化

使用 Declare 的 API 呼叫

呼叫 Windows API 最常見的方式是使用 Declare 陳述式。

若要宣告 DLL 程序

  1. 決定您想要呼叫的函式名稱,加上其引數、引數類型和傳回值,以及包含函式的 DLL 名稱和位置。

    注意

    如需 Windows API 的完整資訊,請參閱 Platform SDK Windows API 中的 Win32 SDK 文件。 如需 Windows API 使用常數的詳細資訊,請檢查 Platform SDK 隨附的標頭檔,例如 Windows.h。

  2. 按一下 [檔案] 功能表上的 [新增],然後按一下 [專案] 以開啟新的 Windows 應用程式專案。 [新增專案] 對話方塊隨即出現。

  3. 從 Visual Basic 專案範本清單中選取 [Windows 應用程式]。 隨即顯示新專案。

  4. 將下列 Declare 函式新增至要在其中使用 DLL 的類別或模組:

    Declare Auto Function MBox Lib "user32.dll" Alias "MessageBox" (
        ByVal hWnd As Integer,
        ByVal txt As String,
        ByVal caption As String,
        ByVal Typ As Integer) As Integer
    

Declare 陳述式的部分

Declare 陳述式包括下列元素。

Auto 修飾元

Auto 修飾元會指示執行階段根據通用語言執行平台規則 (或別名名稱,若有指定) 來轉換基於方法名稱的字串。

Lib 和 Alias 關鍵字

Function 關鍵字後面的名稱是程式用來存取匯入函式的名稱。 此名稱可以與您呼叫函式的實際名稱相同,或者可使用任何有效的程式名稱,然後使用 Alias 關鍵字來指定您所呼叫函式的實際名稱。

指定 Lib 關鍵字,後面接著包含所呼叫函式的 DLL 名稱和位置。 位於 Windows 系統目錄中的檔案不需要指定路徑。

如果您要呼叫的函式名稱不是有效的 Visual Basic 程序名稱,或與應用程式中其他項目的名稱衝突,請使用 Alias 關鍵字。 Alias 表示所呼叫函式的正確名稱。

引數和資料類型宣告

宣告引數及其資料類型。 由於 Windows 使用的資料類型未對應到 Visual Studio 資料類型,所以這個部分可能有許多障礙。 Visual Basic 會將引數轉換成相容的資料類型 (也就是稱為「封送處理」的程式),藉此為您執行許多工作。 您可以使用 System.Runtime.InteropServices 命名空間中定義的 MarshalAsAttribute 屬性,明確控制引數的封送處理方式。

注意

舊版 Visual Basic 允許您宣告參數 As Any,這表示可以使用任何資料類型的資料。 Visual Basic 會要求您針對所有 Declare 陳述式使用特定的資料類型。

Windows API 常數

有些引數是常數的組合。 例如,本逐步解說中顯示的 MessageBox API 會接受名為 Typ 的整數引數,控制訊息框的顯示方式。 您可以檢查 WinUser.h 檔案中的 #define 陳述式來判斷這些常數的數值。 數值通常會以十六進位顯示,因此您可能需要使用計算機將這些數值相加並轉換成十進位。 例如,如果您想要結合驚嘆號樣式 MB_ICONEXCLAMATION 0x00000030 和「是/否」樣式 MB_YESNO 0x00000004 的常數,您可以將數值相加並取得0x00000034或 52 十進位的結果。 雖然您可以直接使用十進位結果,但最好在應用程式中將這些值宣告為常數,並使用 Or 運算子加以合併。

若要宣告 Windows API 呼叫的常數
  1. 請參閱您要呼叫的 Windows 函式文件。 判斷函式所使用的常數名稱,以及包含這些常數數值的 .h 檔案名稱。

  2. 使用記事本之類的文字編輯器來檢視標頭 (.h) 檔的內容,並尋找與您所使用常數相關聯的值。 例如,MessageBox API 會使用 MB_ICONQUESTION 常數在訊息方塊中顯示問號。 MB_ICONQUESTION 的定義位於 WinUser.h 中,如下所示:

    #define MB_ICONQUESTION 0x00000020L

  3. 將相等的 Const 陳述式新增至您的類別或模組,讓您的應用程式可使用這些常數。 例如:

    Const MB_ICONQUESTION As Integer = &H20
    Const MB_YESNO As Integer = &H4
    Const IDYES As Integer = 6
    Const IDNO As Integer = 7
    
若要呼叫 DLL 程序
  1. 將名為 Button1 的按鈕新增至專案的啟動表單,然後按兩下以檢視其程式碼。 隨即顯示按鈕的事件處理常式。

  2. 將程式碼新增至已加入按鈕的 Click 事件處理常式,以呼叫程式並提供適當的引數:

    Private Sub Button1_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button1.Click
    
        ' Stores the return value.
        Dim RetVal As Integer
        RetVal = MBox(0, "Declare DLL Test", "Windows API MessageBox",
            MB_ICONQUESTION Or MB_YESNO)
    
        ' Check the return value.
        If RetVal = IDYES Then
            MsgBox("You chose Yes")
        Else
            MsgBox("You chose No")
        End If
    End Sub
    
  3. 按 F5 執行專案。 訊息方塊會顯示 [是] 和 [否] 回應按鈕。 按一下其中一個選項。

資料封送處理

Visual Basic 會自動轉換 Windows API 呼叫的參數資料類型和傳回值,但您可以使用 MarshalAs 屬性來明確指定 API 預期的非受控資料類型。 如需 Interop 封送處理的詳細資訊,請參閱 Interop 封送處理

若要在 API 呼叫中使用 Declare 和 MarshalAs
  1. 決定您想要呼叫的函式名稱,加上其引數、資料類型和傳回值。

  2. 若要簡化 MarshalAs 屬性的存取,請將 Imports 陳述式新增至類別或模組的程式碼頂端,如下列範例所示:

    Imports System.Runtime.InteropServices
    
  3. 將匯入函式的函式原型新增至您使用的類別或模組,並將 MarshalAs 屬性套用至參數或傳回值。 在下列範例中,API 呼叫預期將類型 void* 做為 AsAny 封送處理:

    Declare Sub SetData Lib "..\LIB\UnmgdLib.dll" (
        ByVal x As Short,
        <MarshalAsAttribute(UnmanagedType.AsAny)>
            ByVal o As Object)
    

使用 DllImport 的 API 呼叫

DllImport 屬性提供第二種方式,可在沒有類型程式庫的 DLL 中呼叫函式。 DllImport 大致上相當於使用 Declare 陳述式,但可更充分控制函式的呼叫方式。

只要呼叫參考共用 (有時稱為「靜態」) 方法,您就可以使用 DllImport 搭配大部分的 Windows API 呼叫。 您無法使用需要類別執行個體的方法。 不同於 Declare 陳述式,DllImport 呼叫無法使用 MarshalAs 屬性。

若要使用 DllImport 屬性呼叫 Windows API

  1. 按一下 [檔案] 功能表上的 [新增],然後按一下 [專案] 以開啟新的 Windows 應用程式專案。 [新增專案] 對話方塊隨即出現。

  2. 從 Visual Basic 專案範本清單中選取 [Windows 應用程式]。 隨即顯示新專案。

  3. 將名為 Button2 的按鈕新增至啟動表單。

  4. 按兩下 Button2 以開啟表單的程式碼檢視。

  5. 若要簡化對 DllImport 的存取,請將 Imports 陳述式新增至啟動表單類別的程式碼頂端:

    Imports System.Runtime.InteropServices
    
  6. 在表單的 End Class 陳述式前面宣告空函式,並將函式命名為 MoveFile

  7. PublicShared 修飾元套用至函式宣告,並根據 Windows API 函式所使用的引數來設定 MoveFile 的參數:

    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    

    您的函式可使用任何有效的程式名稱;DllImport 屬性會指定 DLL 中的名稱。 函式也會處理參數和傳回值的互通性封送處理,因此您可以選擇與 API 所使用資料類型相似的 Visual Studio 資料類型。

  8. DllImport 屬性套用至空函式。 第一個參數是 DLL 的名稱和位置,其中包含您要呼叫的函式。 位於 Windows 系統目錄中的檔案不需要指定路徑。 第二個參數是具名引數,指定 Windows API 中的函式名稱。 在此範例中,DllImport 屬性會強制將針對 MoveFile 的呼叫轉送至 KERNEL32.DLL 中的 MoveFileWMoveFileW 方法會將檔案從路徑 src 複製到路徑 dst

    <DllImport("KERNEL32.DLL", EntryPoint:="MoveFileW", SetLastError:=True,
        CharSet:=CharSet.Unicode, ExactSpelling:=True,
        CallingConvention:=CallingConvention.StdCall)>
    Public Shared Function MoveFile(
        ByVal src As String,
        ByVal dst As String) As Boolean
        ' Leave the body of the function empty.
    End Function
    
  9. 將程式碼新增至 Button2_Click 事件處理常式,以呼叫函式:

    Private Sub Button2_Click(ByVal sender As System.Object,
        ByVal e As System.EventArgs) Handles Button2.Click
    
        Dim RetVal As Boolean = MoveFile("c:\tmp\Test.txt", "c:\Test.txt")
        If RetVal = True Then
            MsgBox("The file was moved successfully.")
        Else
            MsgBox("The file could not be moved.")
        End If
    End Sub
    
  10. 建立名為 Test.txt 的檔案,並將放在硬碟上的 C:\Tmp 目錄中。 如有必要,請建立 Tmp 目錄。

  11. 請按 F5 啟動應用程式。 隨即顯示主要表單。

  12. 按一下 [Button2]。 如果可以移動檔案,則會顯示「已成功移動檔案」訊息。

另請參閱