什么线程的低级鼠标和键盘钩子回调运行?

Tho*_*mas 8 hook winapi multithreading

我正在设置一个低级鼠标钩子SetWindowsHookEx:

HANDLE handle = SetWindowsHookEx(WH_MOUSE_LL, 
                                 &callback, 
                                 GetModuleHandle(NULL), 
                                 NULL);
Run Code Online (Sandbox Code Playgroud)

因为这是一个低级回调,它将在我自己的进程中执行; 没有执行DLL注入.

现在,我注意到回调有时(间接地)从标准API函数调用,例如GetAncestor,GetWindowRect等等.看起来这些可能会导致某些消息队列被刷新.

实际上,我的问题有三个......

  1. 什么叫回调?

    可以从任何 API函数内部调用吗?我怎么说?

  2. 在什么线程上执行回调?

    它只能在安装了挂钩的线程上运行,还是系统可以在任何线程上调用它?

  3. 为什么钩子首先被实现为回调?

    (Raymond Chen在这里闲逛吗?)对于我来说,将钩子简单地实现为(发送)消息似乎更为明智,就像几乎所有其他Windows一样.对于消息,至少我知道哪个功能可能会导致待处理发送的消息将被处理(GetMessage,PeekMessage以及其他的少数),我会知道哪个线程它们被处理(即在第一时间接收到的消息的线程).

Mat*_*lia 9

  1. 见3.

  2. 它在文档中写得非常清楚:

    [...]但是,WH_MOUSE_LL挂钩不会注入另一个进程.相反,上下文切换回安装钩子的进程,并在其原始上下文中调用它.然后上下文切换回生成事件的应用程序.[...] 此挂钩在安装它的线程的上下文中调用.

  3. 实际上它是这样实现的:

    [...]通过向安装了挂钩的线程发送消息来进行调用.因此,安装挂钩的线程必须具有消息循环.

AFAIK,当你的钩子必须被调用时,Windows会在你的线程的消息队列中放入一条特殊的消息.你在消息泵中的代码调用Peek/GetMessage,它检查它是否是特殊消息,如果是,它会调用你的钩子程序(这里有一些证据,我从那里获取了图像). 挂钩调度堆栈http://cboard.cprogramming.com/attachments/windows-programming/9323d1253895425-setwindowshookex-lowlevelmouseproc-hook-callback-callstack-png

  • 如果你能原谅我,我会把头撞到墙上一段时间.非常感谢! (2认同)