SetWindowsHookEx定义如下:
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
idHook是钩子类型,如WH_KEYBOARD捕捉键盘消息,而WH_MOUSE捕捉鼠标消息。hmod用于全局钩子,VB要实现钩子,必须设为0。dwThreadId用于线程钩子VB中可以设置为App.ThreadID。lpfn为钩子函数,在VB中可以使用AddressOf获得钩子函数的地址。这个函数因为钩子类型不同而有所不同。如键盘钩子为:
Public Function KeyboardProc(ByVal nCode As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
如果Code不为0,钩子函数必须调用CallNextHookEx,将消息传递给下面的钩子。wParam和lParam不是按键。
可以到这里看看:http://nhzzljp.vicp.net/Article/show.asp?id=110
你说的那个啥wcHandle
压根就是一个窗口句柄
而SetWindowsHookEx
的第三个参数是
模块句柄
也就是说
你回调函数所在的模块的一个句柄
然后
最后一个参数是
进程id
和你需要进程绑定就可以了
局部钩子
没有写过
一般都写全局
HHOOK
SetWindowsHookEx(int
idHook,
//
钩子的类型,即它处理的消息类型HOOKPROC
lpfn,
//
钩子子程的地址指针。如果dwThreadId参数为0//
或是一个由别的进程创建的线程的标识,//
lpfn必须指向DLL中的钩子子程。//
除此以外,lpfn可以指向当前进程的一段钩子子程代码。// 钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。HINSTANCE
hMod,
//
应用程序实例的句柄。标识包含lpfn所指的子程的DLL。//
如果dwThreadId
标识当前进程创建的一个线程,//
而且子程代码位于当前进程,hMod必须为NULL。//
可以很简单的设定其为本应用程序的实例句柄。DWORD
dwThreadId
//
与安装的钩子子程相关联的线程的标识符。//
如果为0,钩子子程与所有的线程关联,即为全局钩子。)
百科过来的
函数说明
研究到大半夜得出结论是VB做不到这一点,具体原因入下:VB可以写出标准DLL,用一些特殊的插件或者自己编写一些小工具可以做到这一点,百度上我也回答过,验证是可行的,你写的注入代码除了我前面提到过的那一点之外,也都是正确的,但是VB确实每次都会让目标进程崩溃,用IDA查了一下,发现总是死在这个函数里vbaSetSystemError ,在CSDN上查了一下,这个函数是VB编译时候自动加上的,它会检查每次调用API的返回值,但是因为我们是在DLL内部掉API,VB本身设计时没考虑这一点,所以到这个函数里头,它就崩溃了,而我们也没办法阻止我们自己的代码调用这个函数,所以这个只能说是VB自身的问题,确实没办法用VB做线程钩子,只能用VC去做。
查了一下,如何去掉这个函数网上也提了一些说法,不过整体上感觉过于复杂,不值得使用,其中主要的手段就是修改汇编指令,把这个函数从内存里改掉,这个办法通用性差,不值得使用,别的方法就不太有效了。
所以最后总结下来VB就是不支持这么做,没有办法了
============================
Private Declare Function CallNextHookEx Lib "user32" (ByVal hhook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
这个API是从API浏览器上拷贝下来的吧?这么干是不行的。。
必须这样:
Private Declare Function CallNextHookEx Lib "user32" (ByVal hhook As Long, ByVal ncode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
你代码里没有callnexthook,这样恐怕不行吧
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)