VB的API程式設計精粹(二) (轉)

worldblog發表於2007-12-05
VB的API程式設計精粹(二) (轉)[@more@]

第一節:基礎
API說到底就是一系列的底層,是提供給 用於進入核心,進行高階的途徑。通 過在應用中宣告外部過程就能夠 訪問 API(以及其它的外部DLLs)。在宣告 了過程之後,它的方法與呼叫Visual Basic自 己的過程相同。要宣告一個DLL過程,需要在程式碼窗 口的"宣告"部分增加一個Declare語句,如果該過 程返回一個值,應將其宣告為Function。例如:
Declare Function publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]...])] As Type
如果過程沒有返回值,可將其宣告為Sub。
預設情況下,在標準模組中宣告的DLL過程,可 以在應用程式的任何地方呼叫它。在其他型別的模組 中定義的DLL過程是模組私有的,必須在它們前面 加上Private關鍵字,以示區分。特別提請注意的 是,在32位的Visual Basic中過程名是區分大小 寫的。而在以前的16位版本中並不區分大小寫,這 是初學者容易出錯的地方。
Declare語句中的Lib子句用來告訴Visual Basic如何找到包含該過程的dll。如果引用的過 程屬於Windows核心庫(User32、Kernel32或 GDI32),則可以不包含副檔名。例如:
Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount"() As Long。對於其它DLL, Lib子句須指定檔案的路徑及副檔名。
如果呼叫的Windows API過程要使用字串,那 麼在宣告語句中必須增加一個Alias子句,以指定 正確的字符集。包含字串的Windows API函式實 際有兩種格武ANSI格式Unicode格式。因此,在 Windows標頭檔案中,每個包含字串的函式都同時有 ANSI版本和Unicode版本。
例如,下面是SetWindowText函式的兩種C語言描 述。可以看到,第一個描述將函式定義為SetWindowTextA, 尾部的"A"表明它是一個ANSI函式:
SetWindowTextA(HWND hWnd,LPCSTR lpString);
第二個描述將它定義為SetWindowTextW,尾部的 "w"表明它是一個Unicode函式:
SetWindowTextW(HWND Hwnd,LPCWSTR lpString);
因為兩個函式實際的名稱都不是"SetWindow Text",要引用正確的函式就必須增加一個Alias子句:
Private Declare Function SetwindowText Lib "user32" Alias "SetWindowTextA"(ByVal hwnd As Longg,ByVal lpString As String) As Long
請注意, Alias子句後面的字串必須是過程的 真正名稱,必須是區分大小寫的。事實上,您只需要 記住,只有才支援Unicode格式,而 Windows 95只支援ANSI格式就行了。至於兩者的區 別,作一般的應用程式開發是不需要了解的。
VB5專業版在VB目錄的Winapi子目錄下,用幾 個檔案提供了關於API的資訊。 api.txt檔案中 包含了32位Windows API函式中用到的函式和型別的 結構宣告以及全域性常量的值。使用者可以用VB本身帶的外 接程式"API"來方便地使用Win32api.Txt,如下 所示:
點選選單檔案項的"載入文字檔案…"從VB目 錄下的WINAPI目錄中選擇"WIN32API.TXT",就可以 檢視WINDOWS 95系統的API函式的宣告、常數定義和 資料型別了。例如,我們打算檢視函式InverRect() 的宣告。首先,點選"搜尋"按鈕,輸入字串 "InverRect"。在"可選項"欄中,蘭色的亮度條將移 動到"InverRect"項上。再點按"新增"按鈕,在"選 定項"中就出現"InverRect"在Visual Basic中的 宣告瞭。接下來自然是點按"複製"按鈕,然後將窗 口切換到Visual Basic開發環境中,在需要宣告API 函式的地方Ctrl+V(貼上)即可。
上面所講的宣告方法雖然簡單,但只有使用WIN DOWS本身的API函式才能這樣。對於第三方提供的動 態連結庫(DLL)您只有用鍵盤老老實實地敲了。
第二節:牛刀小試
現在讀者一定很想自己親自試一下,下面舉兩個 實際應用的例子讓大家體會一下API的妙用吧!
1.使一個窗體始終保持在螢幕的最上面
我們知道VB本身自帶的函式是難以完成此功能 的,我們可以透過呼叫Windows的API函式: SetWindowPos達到我們的要求。操作步驟如下:
(1)啟動VB5建立一個新工程,在該工程中新增一 個模組(Moudel),在該模組中用上述的"API例覽器" 新增如下的該API函式的函式宣告和常量宣告部分:
'API函式宣告
Declare Function SetWindowPLib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
'常量宣告
Global Const SWP_HWINDOW = &H80
Global Const SWP_NOACTIVATE = &H10
Global Const SWP_NOCOPYBITS = &H100
Global Const SWP_NOMOVE = &H2
Global Const SWP_NOOWNERZORDER = &H200
Global Const SWP_NOREDRAW = &H8
Global Const SWP_NOREPOSITION = SWP_NOOWNERZORDER
Global Const SWP_NOSIZE = &H1
Global Const SWP_NOZORDER = &H4
Global Const SWP_SHOWWINDOW = &H40
Global Const HWND_BOTTOM = 1
Global Const HWND_BROADCAST = &HFFFF&
Global Const HWND_DESKTOP = 0
Global Const HWND_NOTOPMOST = -2
Global Const HWND_TOPMOST = -1
Global Const HWND_TOP = 0
Global Const Flags=SWP_NOMOVE Or SWP_NOSIZE
這裡以"SWP_"開頭的常量是表示窗體所具有的 風格,這些常量可以透過VB中的"OR"運算子組合在 一起。而以"HWND_"開頭的常量表示窗體在桌面上的 位置。從這些常量的英文單詞的意義上讀者應該很容 易理解他們所具有的風格了。所以筆者就不一一去說 明瞭。至於為什麼要新增這些常量而不是別的這就要 您去檢視Windows SDK關於該函式的幫助文件了。當 然這對於初學者來說有一定的難度,但不要畏懼,只 要您仔細看幫助就會慢慢搞懂的。因為這些API函式 是為C和C++的程式設計人員編寫的,所以如果您懂一點 C++的話會很容易理解的。
(2)現在只要在您想要此功能的地方呼叫該函式 就可以了,呼叫的方法如:
Dim Success as Long
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如下程式碼入模組中:
Public Declare Function SystemParametersInfo Lib "user32" Ahias "SystemParametersInfoA" (ByVal uAction As Long,ByVal uParam As Long, lpvParam As Any,ByVal fuWinIni As Long)AS Long
Public Const SPI_SCREENSAVERRUNNING=97
在窗體的程式碼編輯區Copy如下程式碼:
'使三組熱鍵失效
Private Sub cmdDisable_click()
SystemParametersInfo
SPI_SCREENSAVERRUNNING,True,byVal 1&,0
End Sub

Private Sub Form_Unload(Cancel As Integer)
'程式退出前是熱鍵有效
CndEnable_Click
End Sub
若將此功能和螢幕保護程式結合到一起,那您的螢幕 保護程式一定增色許多。
API函式的簡單呼叫例子就是這麼容易,相信現在您 對API的呼叫已不再感到神秘了,接下來我們就看看一個 比較複雜的應用。
第三節:高手進階
上面的關於API的呼叫的例子只是為了帶您去Win dows API世界中去探索一下。相信您已探索到了一點眉 目並想去實現一些更"好玩"的東西了。好!下面就向您 介紹一個很"好玩"同時又會使您的程式看起來更專業化 的一個API呼叫。
相信您的機器上一定裝有"金山詞霸",試著啟動它 您發現了什麼?啟動畫面過後它"不見了"。把滑鼠移到 桌面的右下角,原來它以圖示的形式"藏在" Windows 的托盤中。用滑鼠右擊它還會彈出一個選單功能項供您 選擇。現在您一定想把自己的程式也放到托盤,這樣您的 程式多具有專業水準!
下面是此功能的實現步驟:
1.這裡我們呼叫的API函式是: "_NotifyIcon",在您的模組中新增如下的函式宣告 和常量宣告:
'以下常量告訴系統在托盤中您的圖示上發生了什麼 操作
'常量宣告
Public Const WM_MOUSEMOVE = &H200 '在圖示上移動滑鼠
Public Const WM_LBUTTONDOWN = &H201 '滑鼠左鍵按下
Public Const WM_LBUTTONUP = &H202 '滑鼠左鍵釋放
Public Const WM_LBUTTONLCLK = &H203 '雙擊滑鼠左鍵
Public Const WM_RBUTTONDOWN = &H204 '滑鼠右鍵按下
Public Const WM_RBUTTONUP = &H205 '滑鼠右鍵釋放
Public Const WM_RBUTTONDBLCLK = &H206 '雙擊滑鼠右鍵
Public Const WM_SETHOTKEY = &H32 '響應您定義的熱鍵
'API函式宣告
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
'自定義一個呼叫API Shell_NotifyIcon要用到的類 型"NOTIFYICONDATA"
Public Type NOTIFYICONDATA
cdSize As Long 'NOTIFYICONDATA型別的大小
hwnd As Long '你的應用程式窗體的名柄
uId As Long '應用程式圖示資源的ID號
uFlags As Long '使那些引數有效它是以下列舉型別中的
'NIF_MESSAGE、NIF_ICON、NIF_TIP三組的組合
uCallbackMessage As Long '滑鼠移動時把此訊息發給該圖示的窗體
hIcon As Long '圖示名柄
szTAs String*64 '當滑鼠在圖示上時顯示的Tip文字
End Type

'這是一個列舉型別它告訴API Shell_NotifyIcon去做什麼操作
Public Enum enm_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 '使滑鼠移動訊息有效
End Enum
'定義一個"NOTIFYICONDATA"型別的變數
Public nidPrograta As NOTIFYICONDATA
以上是函式及常量宣告和自定義的一個型別變數,下 面是此API函式的呼叫方法:
2. 在窗體上用選單編輯一個具有如下資訊的選單項:
主選單:無標題、名稱(mainMenu)
子選單:標題(API程式設計)、名稱(submnul);
標題(退出)、名稱(submnu2).
這裡只是舉個例子,具體的功能你可以根據你的具體需要來編輯此選單項
3. 在窗體的Load事件中新增如下程式碼:
Private Sub Form_Load()
'隱藏窗體
With Me
.Top =-10000
.Left = -10000
.WindowState = vbMinimized
End With
'設定型別NOTIFYICONDATA所具有的特徵
With nidprogramData
.cbSize = Len(nidProgramData)
.hwnd = Me.hwnd .uld = vbNull
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
'觸發滑鼠移動訊息
.uCallbackMessage = WM_MOUSEMOVE
.hIcon = Me.Icon '“托盤”中放入窗體圖示,你可以把窗體的圖示換成你所喜歡的圖示
.szTip ="的 Win32 API 程式設計" & vbNullChar
End With

'呼叫該函式
Shell_NotifyIcon NIM_ADD,nidprogramData
End Sub
'根據不同的滑鼠訊息做不同的操作
Private Sub Form_MouseMove(Button As inte ger, Shift As lnteger, x As Single, Y As Single)
On Error GoTo Form_MouseMove_err:
Dim Result As Long
Dim msg As Long
'X的值依賴與顯示的設定
If Me.ScaleMode = vbpixels Then
msg = x
Else
msg = x/Screen.TwipsPerPixe1X
End If
Case msg
Case WM_LBUTTONUP
'在這裡加入滑鼠左鍵釋放時你想做的操作
Case WM_LBUTTONDBLCLK
'在這裡加入雙擊滑鼠左鍵時你想做的操作
Case WM_RBUTTONUP
'通常這裡彈出你的功能選單
PopupMenu mainMenu
Case WM_MOUSEISMOVING
'在這裡加入滑鼠正在移動時你想做的操作
End Select
Exit Sub

Form_MouseMove_err:
'在這裡加入你的處理異常錯誤的程式碼
End Sub
4.Run你的程式,您是不是看到了象“金山詞霸”一樣的功能?相信你此時的感覺一定特別“爽”!

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-988722/,如需轉載,請註明出處,否則將追究法律責任。

相關文章