杨壹琳的回答: Hook简介Hook这个东西有时令人又爱又怕,Hook是用来拦截系统某些讯息之用,例如说,我们想让系统不管在什么地方只要按个CtlB便执行NotePad,或许您会使用Form的KeyPreview,设定为True,但在其他Process中按CtlB呢?那就没有用,这是就得设一个KeyboardHook来拦截所有Keyin的键;再如:MouseMove的Event只在该Form或Control上有效,如果希望在Form的外面也能得知MouseMove的讯息,那只好使用MouseHook来栏截Mouse的讯息。再如:您想记录方才使用者的所有键盘动作或Mosue动作,以便录巨集,那就使用JournalRecordHook,如果想停止所有Mosue键盘的动作,而放(执行)巨集,那就使用JournalPlayBackHHook呢,可以是整个系统为范围(RemoteHook),即其他Process的动作您也可以拦截,也可以是LocalHook,它的拦截范围只有Process本身。RemoteHook的HookFunction要在。Dll之中,LocalHook则在。Bas中。在VB如何设定Hook呢?使用SetWindowsHookEx()DeclareFunctionSetWindowsHookExLibuser32AliasSetWindowsHookExA(ByValidHookAsLong,ByVallpfnAsLong,ByValhmodAsLong,ByValdwThreadIdAsLong)AsLongidHook代表是何种Hook,有以下几种PublicConstWHCALLWNDPROC4PublicConstWHCALLWNDPROCRET12PublicConstWHCBT5PublicConstWHDEBUG9PublicConstWHFOREGROUNDIDLE11PublicConstWHGETMESSAGE3PublicConstWHHARDWARE8PublicConstWHJOURNALPLAYBACK1PublicConstWHJOURNALRECORD0PublicConstWHKEYBOARD2PublicConstWHMOUSE7PublicConstWHMSGFILTER(1)PublicConstWHSHELL10PublicConstWHSYSMSGFILTER6WHCALLWNDPROC当调用SendMessage时WHCALLWNDPROCRET当SendMessage的调用返回时WHGETMESSAGE当调用GetMessage或PeekMessage时WHKEYBOARD当调用GetMessage或PeekMessage来从消息队列中查询WMKEYUP或WMKEYDOWN消息时WHMOUSE当调用GetMessage或PeekMessage来从消息队列中查询鼠标事件消息时WHHARDWARE当调用GetMessage或PeekMessage来从消息队列种查询非鼠标、键盘消息时WHMSGFILTER当对话框、菜单或滚动条要处理一个消息时。该钩子是局部的。它时为那些有自己的消息处理过程的控件对象设计的。WHSYSMSGFILTER和WHMSGFILTER一样,只不过是系统范围的WHJOURNALRECORD当WINDOWS从硬件队列中获得消息时WHJOURNALPLAYBACK当一个事件从系统的硬件输入队列中被请求时WHSHELL当关于WINDOWS外壳事件发生时,譬如任务条需要重画它的按钮。WHCBT当基于计算机的训练(CBT)事件发生时WHFOREGROUNDIDLE由WINDOWS自己使用,一般的应用程序很少使用WHDEBUG用来给钩子函数除错lpfn代表HookFunction所在的Address,这是一个CallBackFucnction,当挂上某个Hook时,我们便得定义一个Function来当作某个讯息产生时,来处理它的Function,这个HookFunction有一定的叁数格式PrivateFunctionHookFunc(ByValncodeAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLongnCode代表是什么请况之下所产生的Hook,随Hook的不同而有不同组的可能值wParamlParam传回值则随Hook的种类和nCode的值之不同而不同。因这个叁数是一个Function的Address所以我们固定将HookFunction放在。Bas中,并以AddressOfHookFunc传入。至于HookFunction的名称我们可以任意给定,不一定叫HookFunchmod代表。DLL的hInstance,如果是LocalHook,该值可以是Null(VB中可传0进去),而如果是RemoteHook,则可以使用GetModuleHandle(。dll名称)来传入。dwThreadId代表执行这个Hook的ThreadId,如果不设定是那个Thread来做,则传0(所以一般来说,RemoteHook传0进去),而VB的LocalHook一般可传app。ThreadId进去值回值如果SetWindowsHookEx()成功,它会传回一个值,代表目前的Hook的Handle,这个值要记录下来。因为A程式可以有一个SystemHook(RemoteHook),如KeyBoardHook,而B程式也来设一个Remote的KeyBoardHook,那么到底KeyBoard的讯息谁所拦截?答案是,最后的那一个所拦截,也就是说A先做keyboardHook,而后B才做,那讯息被B拦截,那A呢?就看B的HookFunction如何做。如果B想让A的HookFunction也得这个讯息,那B就得呼叫CallNextHookEx()将这讯息Pass给A,于是产生Hook的一个连线。如果B中不想Pass这讯息给A,那就不要呼叫CallNextHookEx()。DeclareFunctionCallNextHookExLibuser32(ByValhHookAsLong,ByValncodeAsLong,ByValwParamAsLong,lParamAsAny)AsLonghHook值是SetWindowsHookEx()的传回值,nCode,wParam,lParam则是HookProcedure中的三个叁数。最后是将这Hook去除掉,请呼叫UnHookWindowHookEx()DeclareFunctionUnhookWindowsHookExLibuser32(ByValhHookAsLong)AsLonghHook便是SetWindowsHookEx()的传回值。此时,以上例来说,B程式结束Hook,则换A可以直接拦截讯息。KeyBoardHook的范例HookFunction的三个叁数nCodewParamlParam传回值HCACTION表按键VirtualKey与WMKEYDOWN同若讯息要被处理传0或反之传1HCNOREMOVEPublichHookAsLongPublicSubUnHookKBD()I;0ThenUnhookWindowsHookExhHookhHook0EndIfEndSubPublicFunctionEnableKBDHook()IfhH;0ThenExitFunctionEndIfhHookSetWindowsHookEx(WHKEYBOARD,AddressOfMyKBHFunc,App。hInstance,App。ThreadID)EndFunctionPublicFunctionMyKBHFunc(ByValiCodeAsLong,ByValwParamAsLong,ByVallParamAsLong)AsLongMyKBHFunc0表示要处理这个讯息IfwParamvbKeySnapshotThen侦测有没有按到PrintScreen键MyKBHFunc1在这个Hook便吃掉这个讯息EndIfCallCallNextHookEx(hHook,iCode,wParam,lParam)传给下一个HookEndFunction只要将上面代码放在VB的模块中,用标准VB程序就可以了,当运行该程序后,就能拦截所有键盘操作。 彩虹的微笑的回答: