我正在使用SetWindowsHookEx
设置低级鼠标挂钩:
HANDLE handle = SetWindowsHookEx(WH_MOUSE_LL,
&callback,
GetModuleHandle(NULL),
NULL);
因为这是一个低级回调,它将在我自己的进程中执行;没有执行DLL注入。
现在,我注意到有时(间接)回调来自标准API函数,例如GetAncestor
,GetWindowRect
等。看起来这些可能导致一些消息队列被刷新。
实际上,我的问题有三个......
什么叫回调?
可以从任何 API函数内部调用吗?我怎么说?
执行回调的是什么线程?
它只会在安装了挂钩的线程上运行,还是系统可以在任何线程上调用它?
为什么首先将钩子实现为回调?
(Raymond Chen在这里闲逛吗?)对我来说,简单地将钩子实现为(发送)消息似乎更为明智,就像几乎所有其他Windows一样。对于消息,至少我知道哪些函数可以导致待处理的已发送消息被处理(GetMessage
,PeekMessage
和其他一些消息),并且我知道它们在哪个线程上被处理(该线程是收到消息的第一个地方。)
答案 0 :(得分:9)
见3.
[...]但是,WH_MOUSE_LL挂钩不会注入另一个进程。相反,上下文切换回安装钩子的进程,并在其原始上下文中调用它。然后上下文切换回生成事件的应用程序。 [...] 在安装它的线程的上下文中调用此钩子。
实际上 的实现方式如下:
[...]通过向安装了挂钩的线程发送消息来进行调用。因此,安装挂钩的线程必须具有消息循环。
AFAIK,当你的钩子必须被调用时,Windows会在你的线程的消息队列中放入一条特殊的消息。你在消息泵中的代码调用Peek / GetMessage,它检查它是否是特殊消息,如果是,它会调用你的钩子程序(一些证据here,从那里我拍摄了图像)。 Hook dispatching call stack http://cboard.cprogramming.com/attachments/windows-programming/9323d1253895425-setwindowshookex-lowlevelmouseproc-hook-callback-callstack-png