2010-01-13 102 views
8

我设置与SetWindowsHookEx一个低级别鼠标钩子:低级别鼠标和键盘钩子回调在哪个线程中运行?

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

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

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

其实,我的问题是三倍......

  1. 当调用的回调?

    是否可以从以内调用任何 API函数?我如何看?

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

    它只能在安装钩子的线程上运行,或者系统可以在任何线程上调用它吗?

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

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

回答

8
  1. 请参阅第3

  2. 这是写很清楚在documentation

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

  3. 其实这实现这样的

    [...]呼叫通过发送消息给安装钩子的线。因此,安装该钩子的线程必须有一个消息循环。

据我所知,当你的钩子必须名为Windows在你的线程的消息队列中提出一个特殊的消息。你在消息泵中的代码调用Peek/GetMessage,它检查它是否是特殊消息,如果是,它会调用你的钩子程序(一些证据here,我从那里获取图像)。 Hook dispatching call stack http://cboard.cprogramming.com/attachments/windows-programming/9323d1253895425-setwindowshookex-lowlevelmouseproc-hook-callback-callstack-png

+2

如果你能原谅我,我会把头撞在墙上一会儿。非常感谢! – Thomas 2010-01-14 21:18:12

+0

我的问题是“为什么他们对WH_MOUSE_LL和WH_MOUSE有不同的行为?” (一个需要一个dll,运行在应用程序线程中,一个可以在一个exe文件中,在它自己的线程中)像...这是为了让我们更容易,但它只是针对那些特定的事件,呵呵? – rogerdpack 2013-09-10 20:10:31

+0

@rogerdpack:这大多与原始问题无关,您应该发布您自己的问题。 – 2013-09-10 20:47:48