如此詏定則每當按任一個鎖時,程式自動會去執行 mykbhfunc。這個hook function是由我們所定義,但是它是由window自動去呼叫,而不是由我們的程式呼叫,這類的function就叫callback function。其實,有個更直觴的例子,那就是事件(event);比如說form產生時會有一個form_load事件,在這個事件內我們可以寫很多程式,但這些程式不是給我們其他的procedure呼叫的,而是form在load適來時,由window去呼叫的,這便是callback function。
以上面的例子來說,這個callback function定義如下:
-----------------------------------------------------------------------------
public function mykbhfunc(byval icode as long, _
byval wparam as long, byval lparam as long) as long
mykbhfunc = 0
if icode < 0 then
mykbhfunc = callnexthookex(hnexthookproc, icode, wparam, lparam)
exit function
end if
'偵測 有沒有按到printscreen鎖
if wparam = vbkeysnapshot then
mykbhfunc = 1
debug.print "haha"
end if
end function
-----------------------------------------------------------------------------
這個keyboard hook function的目的主要是想攔截有沒有按到print screen這個鎖,這個鎖不會在form的keydown, keypress, keyup event中作用,所以只好透過keyboard hook去攔截。而callback function放的位置有規定,一個是要與呼叫setwindowshookex() 的地方在同樣的一個project,另外,它只能存在於.bas檔,不能放在其他地方。keyboard hook的程式於範五。
範例五
*****************************************************************************
'以下程式於hook.bas
declare function setwindowshookex lib "user32" alias _
"setwindowshookexa" (byval idhook as long, byval lpfn as long, _
byval hmod as long, byval dwthreadid as long) as long
declare function unhookwindowshookex lib "user32" _
(byval hhook as long) as long
declare function callnexthookex lib "user32" (byval hhook as long, _
byval ncode as long, byval wparam as long, lparam as any) as long
public hnexthookproc as long
public const hc_action = 0
public const wh_keyboard = 2
public sub unhookkbd()
if hnexthookproc <> 0 then
unhookwindowshookex hnexthookproc
hnexthookproc = 0
end if
end sub
public function enablekbdhook()
if hnexthookproc <> 0 then
exit function
end if
hnexthookproc = setwindowshookex(wh_keyboard, addressof _
mykbhfunc, app.hinstance, 0)
if hnexthookproc <> 0 then
enablekbdhook = hnexthookproc
end if
end function
public function mykbhfunc(byval icode as long, _
byval wparam as long, byval lparam as long) as long
'這三個參數是固定的,不能動,而mykbhfunc這個名穛只要和
'setwindowshookex()中 addressof後的名穛一樣便可,不一定叫什黱
mykbhfunc = 0
if icode < 0 then
mykbhfunc = callnexthookex(hnexthookproc, icode, wparam, lparam)
exit function
end if
if wparam = vbkeysnapshot then '偵測 有沒有按到printscreen鎖
mykbhfunc = 1
debug.print "haha"
end if
end function
'以下程式於form
private sub form_load()
call enablekbdhook
end sub
private sub form_unload(cancel as integer)
call unhookkbd
end sub
*****************************************************************************
七、自訂型慴的傳遞
因這只要用byref的方式來做就沒有什黱大的問題,故不做說明。
八、綾合應用
我們再以一個實例來說明win api在vb5中呼叫的技巧。有一個函式叫copymemory的宣告如下:
-----------------------------------------------------------------------------
declare sub copymemory lib "kernel32" alias "rtlmovememory" ( _
lpvdest as any, lpvsource as any, byval cbcopy as long)
-----------------------------------------------------------------------------
這個函式可以將 lpvdest的momory copy 到lpvsource上去,cbcopy則代表要copy多少個byte。有了這個函式,我們可以知道一個double值存在memory中的各個byte到底是多少。
-----------------------------------------------------------------------------
dim dbl as double
dim bte(0 to 7) as byte
dbl = 168.256
copymemory dbl, byt(0), 8
-----------------------------------------------------------------------------
如此檢視bte陣列便可以知道這double值的各個byte是多少。再以另一個journalrecord hook為例來說明:
範例六
*****************************************************************************
' 以下在hook.bas
const wm_mouselast = &h209
const wm_mousefirst = &h200
public const wm_keylast = &h108
public const wm_keyfirst = &h100
public const wh_journalrecord = 0
type eventmsg
message as long
paraml as long