?? vb的api編程精粹.txt
字號:
Public Const STANDARD_RIGHTS_ALL = &H1F0000
Public Const SPECIFIC_RIGHTS_ALL = &HFFFF
'API的返回代碼常量
Public Const ERROR_SUCCESS = 0&
Public Const ERROR_ACCESS_DENIED = 5
Public Const ERROR_NO_MORE_ITEMS = 259
'返回數(shù)值類型常量
Public Const REG_NONE = (0)
Public Const REG_SZ = (1)
Public Const REG_EXPAND_SZ = (2)
Public Const REG_BINARY = (3)
Public Const REG_DWORD = (4)
PubliC ConSt REG_DWORD_LITTLE_ENDIAN = (4)
Public Const REG_DWORD_BIG_ENDIAN = (5)
Public Const REG_LINK = (6)
Public Const REG_MULTI_SZ = (7)
Public Const REG_RESOURCE_LIST = (8)
Public Const REG_FULL_RESOURCE_DESCRIPTOR = (9)
Public Const REG_RESOURCE_REQUIREMENTS_LIST = (10)
'訪問注冊表的API函數(shù)要用到的結(jié)構(gòu)類型
Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Boolean
End Type
Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
'要用到的API函數(shù)聲明
…………
(鑒于篇幅這里只介紹一下各API的作用而不再一一列其聲明;相關(guān)聲明請讀者查閱API瀏覽器)
下面簡單地介紹一下這幾個API:
RegOpenKeyEx():打開指定的關(guān)鍵字(32位);
RegSetValueEx():在打開的注冊表關(guān)鍵字的值域中存儲數(shù)據(jù);
RegCloseKey():釋放指定的關(guān)鍵字的句柄;
VB的API編程精粹(4)
上面所講的聲明方法雖然簡單,但只有使用WIN DOWS本身的API函數(shù)才能這樣。對于第三方提供的動 態(tài)鏈接庫(DLL)您只有用鍵盤老老實實地敲了。
第二節(jié):牛刀小試
現(xiàn)在讀者一定很想自己親自試一下,下面舉兩個 實際應用的例子讓大家體會一下API的妙用吧!
1.使一個窗體始終保持在屏幕的最上面
我們知道VB本身自帶的函數(shù)是難以完成此功能 的,我們可以通過調(diào)用Windows的API函數(shù): SetWindowPos達到我們的要求。操作步驟如下:
(1)啟動VB5建立一個新工程,在該工程中添加一 個模塊(Moudel),在該模塊中用上述的"API例覽器" 添加如下的該API函數(shù)的函數(shù)聲明和常量聲明部分:
'API函數(shù)聲明
Declare Function SetWindowPos Lib "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_HIDEWINDOW = &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關(guān)于該函數(shù)的幫助文檔了。當 然這對于初學者來說有一定的難度,但不要畏懼,只 要您仔細看幫助就會慢慢搞懂的。因為這些API函數(shù) 是為C和C++的編程人員編寫的,所以如果您懂一點 C++的話會很容易理解的。
(2)現(xiàn)在只要在您想要此功能的地方調(diào)用該函數(shù) 就可以了,調(diào)用的方法如:
Dim Success as Long
SuccesS=SetwindowPos(me.HWnd. HWND_TOPMOST,0,0,0,0,FLAGS)
若Success返回的值不等于零則表示調(diào)用成功。
比如在某個窗體的Load事件中加入上述的兩行代 碼,就可以達到使該窗體始終位于屏幕最上面的目的。
細心的讀者可能已經(jīng)發(fā)現(xiàn)上面的例子中的模塊聲 明中聲明了好幾個常量,可為什么只用到三個呢?現(xiàn) 在您可以試著改變一下API函數(shù)"SetWindowPos"中 的第二個參數(shù)或常量FLAGS中的項,看看您的窗體會 出現(xiàn)什么樣的效果?
2.VB5中如何屏蔽掉win95中的CTRL_ALT_DEL, CTRL_ESC, ALT_TAB三組熱鍵通過調(diào)用API函數(shù)"SystemParametersInfo"來實 現(xiàn)。
首先創(chuàng)建一新工程;在此工程中添加一個窗體和 一個模塊;在窗體上拖放兩個按鈕分別命名為 "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
在窗體的代碼編輯區(qū)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
若將此功能和屏幕保護程序結(jié)合到一起,那您的屏幕 保護程序一定增色許多。
API函數(shù)的簡單調(diào)用例子就是這么容易,相信現(xiàn)在您 對API的調(diào)用已不再感到神秘了,接下來我們就看看一個 比較復雜的應用。
第三節(jié):高手進階
上面的關(guān)于API的調(diào)用的例子只是為了帶您去Win dows API世界中去探索一下。相信您已探索到了一點眉 目并想去實現(xiàn)一些更"好玩"的東西了。好!下面就向您 介紹一個很"好玩"同時又會使您的程序看起來更專業(yè)化 的一個API調(diào)用。
相信您的機器上一定裝有"金山詞霸",試著啟動它 您發(fā)現(xiàn)了什么?啟動畫面過后它"不見了"。把鼠標移到 桌面的右下角,原來它以圖標的形式"藏在" Windows 的托盤中。用鼠標右擊它還會彈出一個菜單功能項供您 選擇。現(xiàn)在您一定想把自己的程序也放到托盤,這樣您的 程序多具有專業(yè)水準!
下面是此功能的實現(xiàn)步驟:
1.這里我們調(diào)用的API函數(shù)是: "Shell_NotifyIcon",在您的模塊中添加如下的函數(shù)聲明 和常量聲明:
'以下常量告訴系統(tǒng)在托盤中您的圖標上發(fā)生了什么 操作
'常量聲明
Public Const WM_MOUSEMOVE = &H200 '在圖標上移動鼠標
Public Const WM_LBUTTONDOWN = &H201 '鼠標左鍵按下
Public Const WM_LBUTTONUP = &H202 '鼠標左鍵釋放
Public Const WM_LBUTTONDBLCLK = &H203 '雙擊鼠標左鍵
Public Const WM_RBUTTONDOWN = &H204 '鼠標右鍵按下
Public Const WM_RBUTTONUP = &H205 '鼠標右鍵釋放
Public Const WM_RBUTTONDBLCLK = &H206 '雙擊鼠標右鍵
Public Const WM_SETHOTKEY = &H32 '響應您定義的熱鍵
'API函數(shù)聲明
Public Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias " Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
'自定義一個調(diào)用API Shell_NotifyIcon要用到的類 型"NOTIFYICONDATA"
Public Type NOTIFYICONDATA
cdSize As Long 'NOTIFYICONDATA類型的大小
hwnd As Long '你的應用程序窗體的名柄
uId As Long '應用程序圖標資源的ID號
uFlags As Long '使那些參數(shù)有效它是以下枚舉類型中的
'NIF_MESSAGE、NIF_ICON、NIF_TIP三組的組合
uCallbackMessage As Long '鼠標移動時把此消息發(fā)給該圖標的窗體
hIcon As Long '圖標名柄
szTip As 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 nidProgramData As NOTIFYICONDATA
以上是函數(shù)及常量聲明和自定義的一個類型變量,下 面是此API函數(shù)的調(diào)用方法:
2. 在窗體上用菜單編輯一個具有如下信息的菜單項:
主菜單:無標題、名稱(mainMenu)
子菜單:標題(API編程)、名稱(submnul);
標題(退出)、名稱(submnu2).
這里只是舉個例子,具體的功能你可以根據(jù)你的具體需要來編輯此菜單項
3. 在窗體的Load事件中添加如下代碼:
Private Sub Form_Load()
'隱藏窗體
With Me
.Top =-10000
.Left = -10000
.WindowState = vbMinimized
End With
'設(shè)置類型NOTIFYICONDATA所具有的特征
With nidprogramData
.cbSize = Len(nidProgramData)
.hwnd = Me.hwnd .uld = vbNull
.uFlags = NIF_ICON Or NIF_TIP Or NIF_MESSAGE
'觸發(fā)鼠標移動消息
.uCallbackMessage = WM_MOUSEMOVE
VB的API編程精粹(5)
.hIcon = Me.Icon '“托盤”中放入窗體圖標,你可以把窗體的圖標換成你所喜歡的圖標
.szTip ="VB 的 Win32 API 編程" & vbNullChar
End With
'調(diào)用該函數(shù)
Shell_NotifyIcon NIM_ADD,nidprogramData
End Sub
'根據(jù)不同的鼠標消息做不同的操作
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的值依賴與顯示模式的設(shè)置
If Me.ScaleMode = vbpixels Then
msg = x
Else
msg = x/Screen.TwipsPerPixe1X
End If
Select 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
Visual Basic (VB)作為一種高效編程環(huán)境,它封裝了部分Windows API函數(shù),但也犧牲了一些API的功能。調(diào)用API時稍有不慎就可能導致API編程錯誤,出現(xiàn)難于捕獲或間歇性錯誤,甚至出現(xiàn)程序崩潰。要減少API編程錯誤,提高VB調(diào)用API時的安全性,應重點注意下列八個問題:
(1)指定“Option Explicit”
編程前最好將VB編程環(huán)境中的“Require Variable Declaration(要求變量申明)項選中。如果該項未被指定,任何簡單的錄入錯誤都可能會產(chǎn)生一個“Variant”變量,在調(diào)用API時,VB對該變量進行強制轉(zhuǎn)換以避免沖突,這樣一來,VB就會為字符串、長整數(shù)、整數(shù)、浮點數(shù)等各種類型傳遞NULL值,導致程序無法正常運行。
(2)注意VB整數(shù)和Win32整數(shù)的區(qū)別
在VB環(huán)境下,涉及到的所有integer(整型數(shù)),都是16位,而一旦涉及C/C++Win32文檔時,則是32位,閱讀與Windows API函數(shù)或與32位動態(tài)鏈接庫有關(guān)的資料或應用程序時,尤其要注意分析理解環(huán)境背景,以利于分清數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu),正確地聲明API函數(shù)。
(3)減少和避免使用As Any
雖然用As Any的方法聲明庫,可使Windows API函數(shù)能接受多種類型的參數(shù),但更嚴重的是,即使是一個很小的錯誤,比如遺漏類型標識符或錯誤地使用了ByVal關(guān)鍵字,都可能導致系統(tǒng)崩潰或很難發(fā)現(xiàn)的其他數(shù)據(jù)錯誤。
(4)注意檢查參數(shù)類型
API錯誤中,除了因遺漏ByVal關(guān)鍵字導致的錯誤外,大約有50%是因為聲明中有不正確的參數(shù)類型。在Win32環(huán)境下,無論是8位、16位,還是32位數(shù)值變量都是以32位傳遞,如果同時使用,則很難發(fā)現(xiàn)其中錯誤。如果聲明的參數(shù)類型不同,被VB視為Variant傳遞給API函數(shù),會出現(xiàn)“錯誤的DLL調(diào)用規(guī)范”的消息。
(5)勿忘ByVal,確保函數(shù)聲明的完整性
ByVal是“按值”調(diào)用,參數(shù)傳遞時,不將指向DLL的指針傳遞給參數(shù)變量本身,而是將傳遞參數(shù)值的一份拷貝傳遞給DLL。比如傳遞字符串參數(shù)時,VB與DLL之間的接口支持兩種類型的字符串,如未使用ByVal關(guān)鍵字,VB將指向DLL的函數(shù)指針傳遞給一個OLE2.0字符串(即BSTR數(shù)據(jù)類型),而Windows API函數(shù)往往不支持這種數(shù)據(jù)類型,導致錯誤。而使用ByVal關(guān)鍵字后VB將字符串轉(zhuǎn)變換成C語言格式的“空終止”串,被API正確使用。
(6)重新檢查函數(shù)名
在Win16環(huán)境下,API函數(shù)的名字不要求區(qū)分大小寫,而在Win32環(huán)境下,則有此要求。在一個DLL函數(shù)里找不到聲明的函數(shù)時,有必要檢查一下函數(shù)名,對于管理字符串的函數(shù),是否遺漏了A和W前綴。
(7)預先初始化字符串,以免造成沖突
如果API函數(shù)要求一個指向緩沖區(qū)的指針,以便從中載入數(shù)據(jù),而此時傳遞的是字符串變量,應該先初始化字符串長度。因為API無法知道字符串的長度——API默認已為其分配有足夠的長度。沒有初始化字符串,分配給字符串的緩沖區(qū)有可能會不足,API函數(shù)將有可能在緩沖區(qū)末尾反復改寫,內(nèi)存里字符串后面的內(nèi)容將會改寫得一塌糊涂。程序表現(xiàn)為突然終止或間歇性錯誤。
(8)跟蹤檢查參數(shù)、返回類型和返回值
VB具有立即模式和單步調(diào)試功能,利用這個優(yōu)勢,確保函數(shù)聲明的類型明確(API不返回Variant類型),通過跟蹤和檢查參數(shù)的來源及類型,可以排除參數(shù)的錯誤傳遞。許多API函數(shù)都有返回結(jié)果,指出自己是否執(zhí)行成功。你若要對返回結(jié)果進行測試,用VB的Err對象的LastDllError方法可查閱這些信息,對錯誤可針對API函數(shù)調(diào)用,取回API函數(shù)GetlastError的結(jié)果,以修改聲明,達到正確調(diào)用API函數(shù)之目的。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -