VB5中回調函數的使用方法
發表時間:2024-02-22 來源:明輝站整理相關軟件相關文章人氣:
[摘要]關于回調函數----回調函數(CallbackFunction)是應用程序提供給Windows系統DLL或其它DLL調用的函數,一般用于截獲消息、獲取系統信息或處理異步事件。應用程序把回調函數的地址指針告訴DLL,而DLL在適當的時候會調用該函數。回調函數必須遵守事先規定好的參數格式和傳遞方式,否...
關于回調函數
----回調函數(CallbackFunction)是應用程序提供給Windows系統DLL或其它DLL調用的函數,一般用于截獲消息、獲取系統信息或處理異步事件。應用程序把回調函數的地址指針告訴DLL,而DLL在適當的時候會調用該函數。回調函數必須遵守事先規定好的參數格式和傳遞方式,否則DLL一調用它就會引起程序或系統的崩潰。
----通常情況下,回調函數采用標準WindowsAPI的調用方式,即__stdcall,當然,DLL編制者可以自已定義調用方式,但客戶程序也必須遵守相同的規定。在__stdcall方式下,函數的參數按從右到左的順序壓入堆棧,除了明確指明是指針或引用外,參數都按值傳遞,函數返回之前自己負責把參數從堆棧中彈出。
在VB5中使用函數指針
----假設我們定義了下面的回調函數:
----Public function EnumWindowsProc(ByValhwndAsLong,ByVallParamAsLong)AsLong
----那么可以用"AddressOfEnumWindowsproc"取得它的地址,在WIN32中,這一地址的長度為32位,由于VB中沒有指針的概念,所以函數指針一般都存放在一個Long型變量中,這不會帶來任何問題。
----在VB5中使用函數指針存在不少限制。首先,函數體必須放到標準的.BAS模塊中,而不能放在類模塊或窗體代碼中;其次,AddressOf只能用于自定義的過程、函數或屬性,不能將其用于Declare語句聲明的外部函數,也不能用于類型庫中的函數;最后,寫在AddressOf后面的過程、函數和屬性必須與有關的聲明和過程在同一個工程中。
----AddressOf運算符通常只能出現在函數的參數列表中,一些API函數要求把函數指針存放到一個結構的成員中,并把該結構做為參數傳遞,此時不能直接把AddressOf得到的結果賦給結構成員,而必須要通過一個包裝函數轉換一下。下面的FnPtrToLong可以把函數指針轉換成Long型:
Function FnPtrToLong (ByVal lngFnPtr As Long) As Long
FnPtrToLong = lngFnPtr
End Function
下 面 的 代 碼 把EnumWindowsProc 的函 數 指 針 放 入 到 結 構 中:
Dim mt as MyType
mt.FnPtr = FnPtrToLong(AddressOf EnumWindowsProc)
使用回調函數的簡單例子--枚舉窗口
----為了說明回調函數的使用方法,我們先來看一個實現枚舉窗口功能的簡單例子EnumWnd。
----WIN32API中有一個EnumWindows函數,只要給它提供一個回調函,它就會枚舉出系統中所有頂級窗口,每枚舉一個窗口調用一次回調函數,利用EnumWindows傳遞的窗口句柄,回調函數就可以了解這些窗口的標題、類名稱、是否可見等信息。EnumWindows函數的聲明如下:
----Declare Function EnumWindows Lib"user32" (ByVal lpEnumFunc As Long, _ByVal lParam As Long) As Long
----其中lParam可由應用程序自己任意定義。我們準備把窗口的標題內容顯示在一個列表視窗(ListView)中,這個ListView以Report的形式顯示,共有兩列,分別顯示十六進制的窗口句柄和窗口標題(ListView的具體屬性值見所附程序的完整代碼)。首先給出回調函數EnumWindowsProc的實現代碼:
Public Function EnumWindowsProc
(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim tmpstr As String * 128 ‘ 準 備 緩 沖 區
Dim itmX As ListItem
‘下面判斷是否顯示所有窗口,或者只顯示可見窗口
If frmEnumWnd.optShowWhat(0).Value =
True Or IsWindowVisible(hwnd) Then
GetWindowText hwnd, tmpstr, 127 ‘ 取 回
Set itmX = frmEnumWnd.ListView1.ListItems.Add
(, , "H" & Hex $(hwnd))
itmX.SubItems(1) = tmpstr
Set itmX = Nothing
End If
EnumWindowsProc = True
End Function
然后在窗體代碼中為cmdEnum添加事件處理函數:
Private Sub cmdEnum_Click()
On Error Resume Next
ListView1.ListItems.Clear ‘ 清 除 原 有 數 據
EnumWindows AddressOf EnumWindowsProc,
0 ‘ 傳 遞 回 調 函 數 的 指 針 給EnumWindows 函 數
cmdEnum.Caption = " 重 新 枚 舉"
End Sub
----可見在VB5中使用回調函數并不是特別復雜。不過,EnumWnd中的回調函數屬于比較簡單的情況,因為它不會對系統產生不良影響,我們可以在VB中直接進行調試。下一節的例子中的回調函數要處理Windows系統產生的消息,調試起來要格外小心,如果回調函數中有錯誤,可能會引起非法操作,致使VB運行環境崩潰,因此應隨時注意保存源程序。