明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

怎么手工聲明API

[摘要]盡管 Visual Basic 在 Win32api.txt 中提供了大量的預(yù)定義聲明,但還是需要知道如何親自編寫聲明。例如,有時(shí)希望訪問用其它語言編寫的 DLL 中的過程,或者改寫 Visual Basic 的預(yù)定義聲明,以滿足特殊需要。  要聲明一個(gè) API 過程,需要在代碼窗口的“聲明”部分...
盡管 Visual Basic 在 Win32api.txt 中提供了大量的預(yù)定義聲明,但還是需要知道如何親自編寫聲明。例如,有時(shí)希望訪問用其它語言編寫的 DLL 中的過程,或者改寫 Visual Basic 的預(yù)定義聲明,以滿足特殊需要。
  要聲明一個(gè) API 過程,需要在代碼窗口的“聲明”部分增加一個(gè) Declare 語句。如果該過程返回一個(gè)值,應(yīng)將其聲明為 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]]...])]

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

 

  一.指定庫

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

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

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

.exe 文件所在的目錄


當(dāng)前目錄


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


Windows 目錄(不一定是 \Windows)


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


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


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

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

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

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

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

  因?yàn)閮蓚(gè)函數(shù)實(shí)際的名稱都不是“SetWindowText”,要引用正確的函數(shù)就必須增加一個(gè) Alias 子句:

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

  請(qǐng)注意,Alias 子句后面的字符串必須是過程的真正名稱,而且必須是區(qū)分大小寫的。
  對(duì)于 Visual Basic 中使用的 API 函數(shù),應(yīng)該指定函數(shù)的 ANSI 版本,因?yàn)橹挥?Windows NT 才支持 Unicode 版本,而 Windows 95 不支持這個(gè)版本。僅當(dāng)應(yīng)用程序只運(yùn)行在 Windows NT 平臺(tái)上的時(shí)候才可以使用 Unicode 版本。

 

  三.使用值或引用傳遞

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

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

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


標(biāo)簽:怎樣手工聲明API