明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

如何手工聲明API

[摘要]盡管 Visual Basic 在 Win32api.txt 中提供了大量的預定義聲明,但還是需要知道如何親自編寫聲明。例如,有時希望訪問用其它語言編寫的 DLL 中的過程,或者改寫 Visual Basic 的預定義聲明,以滿足特殊需要! ∫暶饕粋 API 過程,需要在代碼窗口的“聲明”部分...
盡管 Visual Basic 在 Win32api.txt 中提供了大量的預定義聲明,但還是需要知道如何親自編寫聲明。例如,有時希望訪問用其它語言編寫的 DLL 中的過程,或者改寫 Visual Basic 的預定義聲明,以滿足特殊需要。
  要聲明一個 API 過程,需要在代碼窗口的“聲明”部分增加一個 Declare 語句。如果該過程返回一個值,應將其聲明為 Function:

Declare Function publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])] As Type

  如果過程沒有返回值,可將其聲明為 Sub:

Declare Sub publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])]

  缺省情況下,在標準模塊中聲明的 API 過程是公有的,可以在應用程序的任何地方調用它。在其它類型的模塊中定義的 API 過程是模塊私有的,必須在它們前面聲明 Private 關鍵字,以示區(qū)分。

 

  一.指定庫

  Declare 語句中的 Lib 子句用來告訴 Visual Basic 如何找到包含過程的 .API 文件。如果引用的過程屬于 Windows 核心庫(User32、Kernel32 或 GDI32),則可以不包含文件擴展名:

Declare Function GetTickCount Lib "kernel32" Alias _
"GetTickCount" () As Long
  對于其它 DLL,Lib 子句指定文件的路徑:

Declare Function lzCopy Lib "c:\windows\lzexpand.API" _
(ByVal S As Integer, ByVal D As Integer) As Long
  如果未指定 libname 的路徑,Visual Basic 將按照下列順序查找該文件:

.exe 文件所在的目錄


當前目錄


Windows 位系統(tǒng)目錄(通常為 \Windows\System)


Windows 目錄(不一定是 \Windows)


Path 環(huán)境變量中的目錄


下表中列出了通常的操作系統(tǒng)環(huán)境庫文件。
動態(tài)鏈接庫 描述
Advapi32.API 高級 API 服務,支持大量的 API(其中包括許多安全與注冊方面的調用)
Comdlg32.API 通用對話框 API 庫
Gdi32.API 圖形設備接口 API 庫
Kernel32.API Windows 32 位核心的 API 支持
Lz32.API 32 位壓縮例程
Mpr.API 多接口路由器庫
Netapi32.API 32 位網絡 API 庫
Shell32.API 32 位 Shell API 庫
User32.API 用戶接口例程庫
Version.API 版本庫
Winmm.API Windows 多媒體庫
Winspool.drv 后臺打印接口,包含后臺打印 API 調用。


  二.處理使用字符串的 Windows API 過程

  如果調用的 Windows API 過程要使用字符串,那么聲明語句中必須增加一個 Alias 子句,以指定正確的字符集。包含字符串的 Windows API 函數(shù)實際有兩種格式:ANSI 和 Unicode。因此,在 Windows 頭文件中,每個包含字符串的函數(shù)都同時有 ANSI 版本和 Unicode 版本。
  例如,下面是 SetWindowText 函數(shù)的兩種 C 語言描述。可以看到,第一個描述將函數(shù)定義為 SetWindowTextA,尾部的“A”表明它是一個 ANSI 函數(shù):

WINUSERAPI
BOOL
WINAPI
SetWindowTextA(
HWND hWnd,
LPCSTR lpString);

  第二個描述將它定義為 SetWindowTextW,尾部的“W”表明它是一個 Unicode 函數(shù):

WINUSERAPI
BOOL
WINAPI
SetWindowTextW(
HWND hWnd,
LPCWSTR lpString);

  因為兩個函數(shù)實際的名稱都不是“SetWindowText”,要引用正確的函數(shù)就必須增加一個 Alias 子句:

Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal _
lpString As String) As Long

  請注意,Alias 子句后面的字符串必須是過程的真正名稱,而且必須是區(qū)分大小寫的。
  對于 Visual Basic 中使用的 API 函數(shù),應該指定函數(shù)的 ANSI 版本,因為只有 Windows NT 才支持 Unicode 版本,而 Windows 95 不支持這個版本。僅當應用程序只運行在 Windows NT 平臺上的時候才可以使用 Unicode 版本。

 

  三.使用值或引用傳遞

  在缺省的情況下,Visual Basic 以引用方式傳遞所有參數(shù)。這意味著并沒有傳遞實際的參數(shù)值,Visual Basic 只傳遞了數(shù)據(jù)的 32 位地址。在 Declare 語句中不要求包含 ByRef 關鍵字,但是如果包含該關鍵字,就能夠清楚地看出數(shù)據(jù)是以何種方式傳遞的。
  許多 API 過程要求參數(shù)以值方式傳遞。這意味著它們需要實際的數(shù)據(jù),而不是數(shù)據(jù)的內存地址。如果過程需要一個傳值參數(shù),而傳遞給它的參數(shù)是一個指針,那么由于得到了錯誤的數(shù)據(jù),該過程將不能正確地工作。
  要使參數(shù)以使用值方式傳遞,在 Declare 語句中需要在參數(shù)聲明的前面加上 ByVal 關鍵字。例如,InvertRect 過程要求第一個參數(shù)使用值,而第二個使用引用:

Declare Function InvertRect Lib "user32" Alias _
"InvertRectA" (ByVal hdc As Long, _
lpRect As RECT) As Long

  也可以在調用過程時使用 ByVal 關鍵字。
  字符串參數(shù)是一個特例。如果以使用值方式傳遞字符串,那么傳遞的將是該字符串中第一個數(shù)據(jù)字節(jié)的地址;如果以使用引用方式傳遞字符串,那么實際傳遞的將是用來保存另一個地址的內存單元的地址;后面的“地址”實際是字符串的第一個數(shù)據(jù)字節(jié)的內存地址。