【问题标题】:In what thread does a low-level mouse and keyboard hook callback run?低级鼠标和键盘挂钩回调在哪个线程中运行?
【发布时间】:2011-01-04 20:16:07
【问题描述】:

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

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

因为这是一个低级回调,所以会在我自己的进程内部执行;不执行 DLL 注入。

现在,我注意到有时(间接地)从标准 API 函数(例如 GetAncestor、GetWindowRect 等)调用回调。似乎这些会导致一些消息队列被刷新。

其实,我的问题有三个……

  1. 什么时候调用回调?

    可以从 any API 函数内部调用它吗?我怎么知道?

  2. 回调在哪个线程上执行?

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

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

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

【问题讨论】:

    标签: winapi multithreading hook


    【解决方案1】:
    1. 见 3。

    2. documentation里写得很清楚:

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

    1. 其实它是这样实现的:

    [...] 通过向安装钩子的线程发送消息来进行调用。所以,安装hook的线程一定是有消息循环的。

    AFAIK,当你的钩子必须被调用时,Windows 会在你的线程的消息队列中放入一条特殊的消息。您在消息泵中的代码调用 Peek/GetMessage,它会检查它是否是特殊消息,如果是,它会调用您的钩子程序(一些证据 here,我拍摄图像的地方)。
    (来源:cprogramming.com)

    【讨论】:

    • 如果你能原谅我,我会去撞墙一会儿。非常感谢!
    • 我的问题是“为什么他们对 WH_MOUSE_LL 和 WH_MOUSE 有不同的行为?” (一个需要一个 dll,在应用程序线程中运行,一个可以在一个 exe 中工作,在它自己的线程中)就像......这是为了让我们更容易,但它只适用于那些特定的事件,对吧?跨度>
    • @rogerdpack:这与原始问题几乎无关,您应该发布自己的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多