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

时间:2010-01-13 21:17:17

标签: winapi multithreading hook

我正在使用SetWindowsHookEx设置低级鼠标挂钩:

HANDLE handle = SetWindowsHookEx(WH_MOUSE_LL, 
                                 &callback, 
                                 GetModuleHandle(NULL), 
                                 NULL);

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

现在,我注意到有时(间接)回调来自标准API函数,例如GetAncestorGetWindowRect等。看起来这些可能导致一些消息队列被刷新。

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

  1. 什么叫回调?

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

  2. 执行回调的是什么线程?

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

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

    (Raymond Chen在这里闲逛吗?)对我来说,简单地将钩子实现为(发送)消息似乎更为明智,就像几乎所有其他Windows一样。对于消息,至少我知道哪些函数可以导致待处理的已发送消息被处理(GetMessagePeekMessage和其他一些消息),并且我知道它们在哪个线程上被处理(该线程是收到消息的第一个地方。)

1 个答案:

答案 0 :(得分:9)

  1. 见3.

  2. documentation

    中写得非常清楚
      

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

  3. 实际上 的实现方式如下:

      

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

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