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

VB5中回調(diào)函數(shù)的使用方法

[摘要]關(guān)于回調(diào)函數(shù)----回調(diào)函數(shù)(CallbackFunction)是應(yīng)用程序提供給Windows系統(tǒng)DLL或其它DLL調(diào)用的函數(shù),一般用于截獲消息、獲取系統(tǒng)信息或處理異步事件。應(yīng)用程序把回調(diào)函數(shù)的地址指針告訴DLL,而DLL在適當(dāng)?shù)臅r候會調(diào)用該函數(shù)。回調(diào)函數(shù)必須遵守事先規(guī)定好的參數(shù)格式和傳遞方式,否...
關(guān)于回調(diào)函數(shù)
----回調(diào)函數(shù)(CallbackFunction)是應(yīng)用程序提供給Windows系統(tǒng)DLL或其它DLL調(diào)用的函數(shù),一般用于截獲消息、獲取系統(tǒng)信息或處理異步事件。應(yīng)用程序把回調(diào)函數(shù)的地址指針告訴DLL,而DLL在適當(dāng)?shù)臅r候會調(diào)用該函數(shù);卣{(diào)函數(shù)必須遵守事先規(guī)定好的參數(shù)格式和傳遞方式,否則DLL一調(diào)用它就會引起程序或系統(tǒng)的崩潰。
----通常情況下,回調(diào)函數(shù)采用標(biāo)準(zhǔn)WindowsAPI的調(diào)用方式,即__stdcall,當(dāng)然,DLL編制者可以自已定義調(diào)用方式,但客戶程序也必須遵守相同的規(guī)定。在__stdcall方式下,函數(shù)的參數(shù)按從右到左的順序壓入堆棧,除了明確指明是指針或引用外,參數(shù)都按值傳遞,函數(shù)返回之前自己負(fù)責(zé)把參數(shù)從堆棧中彈出。

在VB5中使用函數(shù)指針
----假設(shè)我們定義了下面的回調(diào)函數(shù):

----Public function EnumWindowsProc(ByValhwndAsLong,ByVallParamAsLong)AsLong

----那么可以用"AddressOfEnumWindowsproc"取得它的地址,在WIN32中,這一地址的長度為32位,由于VB中沒有指針的概念,所以函數(shù)指針一般都存放在一個Long型變量中,這不會帶來任何問題。

----在VB5中使用函數(shù)指針存在不少限制。首先,函數(shù)體必須放到標(biāo)準(zhǔn)的.BAS模塊中,而不能放在類模塊或窗體代碼中;其次,AddressOf只能用于自定義的過程、函數(shù)或?qū)傩,不能將其用于Declare語句聲明的外部函數(shù),也不能用于類型庫中的函數(shù);最后,寫在AddressOf后面的過程、函數(shù)和屬性必須與有關(guān)的聲明和過程在同一個工程中。

----AddressOf運算符通常只能出現(xiàn)在函數(shù)的參數(shù)列表中,一些API函數(shù)要求把函數(shù)指針存放到一個結(jié)構(gòu)的成員中,并把該結(jié)構(gòu)做為參數(shù)傳遞,此時不能直接把AddressOf得到的結(jié)果賦給結(jié)構(gòu)成員,而必須要通過一個包裝函數(shù)轉(zhuǎn)換一下。下面的FnPtrToLong可以把函數(shù)指針轉(zhuǎn)換成Long型:

   Function FnPtrToLong (ByVal lngFnPtr As Long) As Long
   FnPtrToLong = lngFnPtr
   End Function
    下 面 的 代 碼 把EnumWindowsProc 的函 數(shù) 指 針 放 入 到 結(jié) 構(gòu) 中:
   Dim mt as MyType
   mt.FnPtr = FnPtrToLong(AddressOf EnumWindowsProc)
使用回調(diào)函數(shù)的簡單例子--枚舉窗口
----為了說明回調(diào)函數(shù)的使用方法,我們先來看一個實現(xiàn)枚舉窗口功能的簡單例子EnumWnd。

----WIN32API中有一個EnumWindows函數(shù),只要給它提供一個回調(diào)函,它就會枚舉出系統(tǒng)中所有頂級窗口,每枚舉一個窗口調(diào)用一次回調(diào)函數(shù),利用EnumWindows傳遞的窗口句柄,回調(diào)函數(shù)就可以了解這些窗口的標(biāo)題、類名稱、是否可見等信息。EnumWindows函數(shù)的聲明如下:

----Declare Function EnumWindows Lib"user32" (ByVal lpEnumFunc As Long, _ByVal lParam As Long) As Long

----其中l(wèi)Param可由應(yīng)用程序自己任意定義。我們準(zhǔn)備把窗口的標(biāo)題內(nèi)容顯示在一個列表視窗(ListView)中,這個ListView以Report的形式顯示,共有兩列,分別顯示十六進(jìn)制的窗口句柄和窗口標(biāo)題(ListView的具體屬性值見所附程序的完整代碼)。首先給出回調(diào)函數(shù)EnumWindowsProc的實現(xiàn)代碼:

Public Function EnumWindowsProc
(ByVal hwnd As Long, ByVal lParam As Long) As Long
 Dim tmpstr As String * 128 ‘ 準(zhǔn) 備 緩 沖 區(qū)
 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添加事件處理函數(shù):
 Private Sub cmdEnum_Click()
 On Error Resume Next
 ListView1.ListItems.Clear ‘ 清 除 原 有 數(shù) 據(jù)
 EnumWindows AddressOf EnumWindowsProc,
0 ‘ 傳 遞 回 調(diào) 函 數(shù) 的 指 針 給EnumWindows 函 數(shù)
 cmdEnum.Caption = " 重 新 枚 舉"
 End Sub
----可見在VB5中使用回調(diào)函數(shù)并不是特別復(fù)雜。不過,EnumWnd中的回調(diào)函數(shù)屬于比較簡單的情況,因為它不會對系統(tǒng)產(chǎn)生不良影響,我們可以在VB中直接進(jìn)行調(diào)試。下一節(jié)的例子中的回調(diào)函數(shù)要處理Windows系統(tǒng)產(chǎn)生的消息,調(diào)試起來要格外小心,如果回調(diào)函數(shù)中有錯誤,可能會引起非法操作,致使VB運行環(huán)境崩潰,因此應(yīng)隨時注意保存源程序。