VisualBasic以友好易學的可視化開發環境聞名於世,成為人們學習計算機編程的首選語言。目前,全世界大概有300多萬人使用著VisualBasic語言。如果您想在這茫茫眾生中出類拔萃,那麼您就不得不學習API(ApplicationProgramlnterface,即Windows的應用程序編程接口)編程。不懂API,那可成不了高手。
第一節:API基礎
API說到底就是一系列的底層函數,是系統提供給用戶用於進入操作系統核心,進行高級編程的途徑。通過在VisualBasic應用程序中聲明外部過程就能夠訪問WindowsAPI(以及其它的外部DLLs)。在聲明了過程之後,調用它的方法與調用VisualBasic自己的過程相同。要聲明一個DLL過程,需要在代碼窗口的"聲明"部分增加一個Declare語句,如果該過程返回一個值,應將其聲明為Function。例如:
DeclareFunctionpublicnameLib"libname"[Alias"alias"][([[ByVal]variable[Astype][,[ByVal]variable[Astype]]...])]AsType
如果過程沒有返回值,可將其聲明為Sub。
缺省情況下,在標准模塊中聲明的DLL過程,可以在應用程序的任何地方調用它。在其他類型的模塊中定義的DLL過程是模塊私有的,必須在它們前面加上Private關鍵字,以示區分。特別提請注意的是,在32位的VisualBasic中過程名是區分大小寫的。而在以前的16位版本中並不區分大小寫,這是初學者容易出錯的地方。
Declare語句中的Lib子句用來告訴VisualBasic如何找到包含該過程的dll文件。如果引用的過程屬於Windows核心庫(User32、Kernel32或GDI32),則可以不包含文件擴展名。例如:
DeclareFunctionGetTickCountLib"kernel32"Alias"GetTickCount"()AsLong。對於其它DLL,Lib子句須指定文件的路徑及擴展名。
如果調用的WindowsAPI過程要使用字符串,那麼在聲明語句中必須增加一個Alias子句,以指定正確的字符集。包含字符串的WindowsAPI函數實際有兩種格武ANSI格式Unicode格式。因此,在Windows頭文件中,每個包含字符串的函數都同時有ANSI版本和Unicode版本。
例如,下面是SetWindowText函數的兩種C語言描述。可以看到,第一個描述將函數定義為SetWindowTextA,尾部的"A"表明它是一個ANSI函數:
SetWindowTextA(HWNDhWnd,LPCSTRlpString);
第二個描述將它定義為SetWindowTextW,尾部的"w"表明它是一個Unicode函數:
SetWindowTextW(HWNDHwnd,LPCWSTRlpString);
因為兩個函數實際的名稱都不是"SetWindowText",要引用正確的函數就必須增加一個Alias子句:
PrivateDeclareFunctionSetwindowTextLib"user32"Alias"SetWindowTextA"(ByValhwndAsLongg,ByVallpStringAsString)AsLong
請注意,Alias子句後面的字符串必須是過程的真正名稱,必須是區分大小寫的。事實上,您只需要記住,只有WindowsNT才支持Unicode格式,而Windows95只支持ANSI格式就行了。至於兩者的區別,作一般的應用程序開發是不需要了解的。
VB5專業版在VB目錄的Winapi子目錄下,用幾個文件提供了關於API的信息。Win32api.txt文件中包含了32位WindowsAPI函數中用到的函數和類型的結構聲明以及全局常量的值。用戶可以用VB本身帶的外接程序"API浏覽器"來方便地使用Win32api.Txt,如下所示:
點擊菜單文件項的"加載文本文件…"從VB目錄下的WINAPI目錄中選擇"WIN32API.TXT",就可以查看WINDOWS95系統的API函數的聲明、常數定義和數據類型了。例如,我們打算查看函數InverRect()的聲明。首先,點擊"搜索"按鈕,輸入字符串"InverRect"。在"可選項"欄中,蘭色的亮度條將移動到"InverRect"項上。再點按"添加"按鈕,在"選定項"中就出現"InverRect"在VisualBasic中的聲明了。接下來自然是點按"復制"按鈕,然後將窗口切換到VisualBasic開發環境中,在需要聲明API函數的地方Ctrl+V(粘貼)即可。
上面所講的聲明方法雖然簡單,但只有使用WINDOWS本身的API函數才能這樣。對於第三方提供的動態鏈接庫(DLL)您只有用鍵盤老老實實地敲了。
第二節:牛刀小試
現在讀者一定很想自己親自試一下,下面舉兩個實際應用的例子讓大家體會一下API的妙用吧!
1.使一個窗體始終保持在屏幕的最上面
我們知道VB本身自帶的函數是難以完成此功能的,我們可以通過調用Windows的API函數:SetWindowPos達到我們的要求。操作步驟如下:
(1)啟動VB5建立一個新工程,在該工程中添加一個模塊(Moudel),在該模塊中用上述的"API例覽器"添加如下的該API函數的函數聲明和常量聲明部分:
'API函數聲明
DeclareFunctionSetWindowPosLib"user32"Alias"SetWindowPos"(ByValhwndAsLong,ByValhWndInsertAfterAsLong,ByValxAsLong,ByValyAsLong,ByValcxAsLong,ByValcyAsLong,ByValwFlagsAsLong)AsLong
'常量聲明
GlobalConstSWP_HIDEWINDOW=&H80
GlobalConstSWP_NOACTIVATE=&H10
GlobalConstSWP_NOCOPYBITS=&H100
GlobalConstSWP_NOMOVE=&H2
GlobalConstSWP_NOOWNERZORDER=&H200
GlobalConstSWP_NOREDRAW=&H8
GlobalConstSWP_NOREPOSITION=SWP_NOOWNERZORDER
GlobalConstSWP_NOSIZE=&H1
GlobalConstSWP_NOZORDER=&H4
GlobalConstSWP_SHOWWINDOW=&H40
GlobalConstHWND_BOTTOM=1
GlobalConstHWND_BROADCAST=&HFFFF&
GlobalConstHWND_DESKTOP=0
GlobalConstHWND_NOTOPMOST=-2
GlobalConstHWND_TOPMOST=-1
GlobalConstHWND_TOP=0
GlobalConstFlags=SWP_NOMOVEOrSWP_NOSIZE
這裡以"SWP_"開頭的常量是表示窗體所具有的風格,這些常量可以通過VB中的"OR"操作符組合在一起。而以"HWND_"開頭的常量表示窗體在桌面上的位置。從這些常量的英文單詞的意義上讀者應該很容易理解他們所具有的風格了。所以筆者就不一一去說明了。至於為什麼要添加這些常量而不是別的這就要您去查看WindowsSDK關於該函數的幫助文檔了。當然這對於初學者來說有一定的難度,但不要畏懼,只要您仔細看幫助就會慢慢搞懂的。因為這些API函數是為C和C++的編程人員編寫的,所以如果您懂一點C 的話會很容易理解的。
(2)現在只要在您想要此功能的地方調用該函數就可以了,調用的方法如:
DimSuccessasLong
SuccesS=SetwindowPos(me.HWnd.HWND_TOPMOST,0,0,0,0,FLAGS)
若Success返回的值不等於零則表示調用成功。
比如在某個窗體的Load事件中加入上述的兩行代碼,就可以達到使該窗體始終位於屏幕最上面的目的。
細心的讀者可能已經發現上面的例子中的模塊聲明中聲明了好幾個常量,可為什麼只用到三個呢?現在您可以試著改變一下API函數"SetWindowPos"中的第二個參數或常量FLAGS中的項,看看您的窗體會出現什麼樣的效果?
2.VB5中如何屏蔽掉win95中的CTRL_ALT_DEL,CTRL_ESC,ALT_TAB三組熱鍵通過調用API函數"SystemParametersInfo"來實現。
首先創建一新工程;在此工程中添加一個窗體和一個模塊;在窗體上拖放兩個按鈕分別命名為"cmdDisable","cmdEnable";Copy如下代碼入模塊中:
PublicDeclareFunctionSystemParametersInfoLib"user32"Ahias"SystemParametersInfoA"(ByValuActionAsLong,ByValuParamAsLong,lpvParamAsAny,ByValfuWinIniAsLong)ASLong
PublicConstSPI_SCREENSAVERRUNNING=97
在窗體的代碼編輯區Copy如下代碼:
'使三組熱鍵失效
PrivateSubcmdDisable_click()
SystemParametersInfo
SPI_SCREENSAVERRUNNING,True,byVal1&,0
EndSub
PrivateSubForm_Unload(CancelAsInteger)
'程序退出前是熱鍵有效
CndEnable_Click
EndSub
若將此功能和屏幕保護程序結合到一起,那您的屏幕保護程序一定增色許多。
API函數的簡單調用例子就是這麼容易,相信現在您對API的調用已不再感到神秘了,接下來我們就看看一個比較復雜的應用。
第三節:高手進階
上面的關於API的調用的例子只是為了帶您去WindowsAPI世界中去探索一下。相信您已探索到了一點眉目並想去實現一些更"好玩"的東西了。好!下面就向您介紹一個很"好玩"同時又會使您的程序看起來更專業化的一個API調用。
相信您的機器上一定裝有"金山詞霸",試著啟動它您發現了什麼?啟動畫面過後它"不見了"。把鼠標移到桌面的右下角,原來它以圖標的形式"藏在"Windows的托盤中。用鼠標右擊它還會彈出一個菜單功能項供您選擇。現在您一定想把自己的程序也放到托盤,這樣您的程序多具有專業水准!
下面是此功能的實現步驟:
1.這裡我們調用的API函數是:"Shell_NotifyIcon",在您的模塊中添加如下的函數聲明和常量聲明:
'以下常量告訴系統在托盤中您的圖標上發生了什麼操作
'常量聲明
PublicConstWM_MOUSEMOVE=&H200'在圖標上移動鼠標
PublicConstWM_LBUTTONDOWN=&H201'鼠標左鍵按下
PublicConstWM_LBUTTONUP=&H202'鼠標左鍵釋放
PublicConstWM_LBUTTONDBLCLK=&H203'雙擊鼠標左鍵
PublicConstWM_RBUTTONDOWN=&H204'鼠標右鍵按下
PublicConstWM_RBUTTONUP=&H205'鼠標右鍵釋放
PublicConstWM_RBUTTONDBLCLK=&H206'雙擊鼠標右鍵
PublicConstWM_SETHOTKEY=&H32'響應您定義的熱鍵
'API函數聲明
PublicDeclareFunctionShell_NotifyIconLib"shell32.dll"Alias"Shell_NotifyIconA"(ByValdwMessageAsLong,lpDataAsNOTIFYICONDATA)AsLong
'自定義一個調用APIShell_NotifyIcon要用到的類型"NOTIFYICONDATA"
PublicTypeNOTIFYICONDATA
cdSizeAsLong'NOTIFYICONDATA類型的大小
hwndAsLong'你的應用程序窗體的名柄
uIdAsLong'應用程序圖標資源的ID號
uFlagsAsLong'使那些參數有效它是以下枚舉類型中的
'NIF_MESSAGE、NIF_ICON、NIF_TIP三組的組合
uCallbackMessageAsLong'鼠標移動時把此消息發給該圖標的窗體
hIconAsLong'圖標名柄
szTipAsString*64'當鼠標在圖標上時顯示的Tip文本
EndType
'這是一個枚舉類型它告訴APIShell_NotifyIcon去做什麼操作
PublicEnumenm_NIM_Shell
NIM_ADD=&H40'在“金碟”中加一圖標
NIM_MODIFY=&H1'修改“金碟”中的圖標
NIM_DELETE=&H2'刪除“金碟”中的圖標
NIF_MESSAGE=&H1'使類型"NOTIFYICONDATA"中的uCallbackMessage有效
NIF_ICON=&H2'使類型"NOTIFYICONDATA"中的hIcon有效
NIF_TIP=&H4'使類型"NOTIFYICONDATA"中的szTip有效
WM_MOUSEMOVE=&H200'使鼠標移動消息有效
EndEnum
'定義一個"NOTIFYICONDATA"類型的變量
PublicnidProgramDataAsNOTIFYICONDATA
以上是函數及常量聲明和自定義的一個類型變量,下面是此API函數的調用方法:
2.在窗體上用菜單編輯一個具有如下信息的菜單項:
主菜單:無標題、名稱(mainMenu)
子菜單:標題(API編程)、名稱(submnul);
標題(退出)、名稱(submnu2).
這裡只是舉個例子,具體的功能你可以根據你的具體需要來編輯此菜單項
3.在窗體的Load事件中添加如下代碼:
PrivateSubForm_Load()
'隱藏窗體
WithMe
.Top=-10000
.Left=-10000
.WindowState=vbMinimized
EndWith
'設置類型NOTIFYICONDATA所具有的特征
WithnidprogramData
.cbSize=Len(nidProgramData)
.hwnd=Me.hwnd.uld=vbNull
.uFlags=NIF_ICONOrNIF_TIPOrNIF_MESSAGE
'觸發鼠標移動消息
.uCallbackMessage=WM_MOUSEMOVE
.hIcon=Me.Icon'“托盤”中放入窗體圖標,你可以把窗體的圖標換成你所喜歡的圖標
.szTip="VB的Win32API編程"&vbNullChar
EndWith
'調用該函數
Shell_NotifyIconNIM_ADD,nidprogramData
EndSub
'根據不同的鼠標消息做不同的操作
PrivateSubForm_MouseMove(ButtonAsinteger,ShiftAslnteger,xAsSingle,YAsSingle)
OnErrorGoToForm_MouseMove_err:
DimResultAsLong
DimmsgAsLong
'X的值依賴與顯示模式的設置
IfMe.ScaleMode=vbpixelsThen
msg=x
Else
msg=x/Screen.TwipsPerPixe1X
EndIf
SelectCasemsg
CaseWM_LBUTTONUP
'在這裡加入鼠標左鍵釋放時你想做的操作
CaseWM_LBUTTONDBLCLK
'在這裡加入雙擊鼠標左鍵時你想做的操作
CaseWM_RBUTTONUP
'通常這裡彈出你的功能菜單
PopupMenumainMenu
CaseWM_MOUSEISMOVING
'在這裡加入鼠標正在移動時你想做的操作
EndSelect
ExitSub
Form_MouseMove_err:
'在這裡加入你的處理異常錯誤的代碼
EndSub
4.Run你的程序,您是不是看到了象“金山詞霸”一樣的功能?相信你此時的感覺一定特別“爽”!
API的世界j是豐富多彩的,只要你肯細心地去探索它你一定會獲得許多意想不到的好東西。所以筆者覺得定值得每一個具有“好奇”精神的人去探索它。後續的期刊筆者會向讀者詳細介紹一些更好更“牛”的API調用。->