Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 什么键盘钩子不会被调用_C#_C++_Winapi_Visual C++_Hook - Fatal编程技术网

C# 什么键盘钩子不会被调用

C# 什么键盘钩子不会被调用,c#,c++,winapi,visual-c++,hook,C#,C++,Winapi,Visual C++,Hook,我的WH\u键盘\u LLhook出现了一些问题: 我使用全局LL钩子的原因并不重要,我只是在我的应用程序中需要它(我尝试了其他类型的钩子,但它们对我不起作用) 钩子函数位于dll中,dll在应用程序启动时加载,钩子也在主线程启动时设置。这很好用。当我需要停用钩子并重新激活它时,问题就会出现。如果我在应用程序的主线程中这样做,它可以正常工作,但我需要的是在计时器中这样做,这里出现了问题。我使用计时器检查我的应用程序窗口是否是前台窗口(活动窗口),如果是,钩子被激活,如果不是,钩子被停用。当从计时

我的
WH\u键盘\u LL
hook出现了一些问题:

我使用全局LL钩子的原因并不重要,我只是在我的应用程序中需要它(我尝试了其他类型的钩子,但它们对我不起作用)

钩子函数位于dll中,dll在应用程序启动时加载,钩子也在主线程启动时设置。这很好用。当我需要停用钩子并重新激活它时,问题就会出现。如果我在应用程序的主线程中这样做,它可以正常工作,但我需要的是在计时器中这样做,这里出现了问题。我使用计时器检查我的应用程序窗口是否是前台窗口(活动窗口),如果是,钩子被激活,如果不是,钩子被停用。当从计时器调用时,
SetWindowsHookEx
的返回值总是ok(非null),根据MSDN,这意味着钩子设置成功,但我的钩子函数从未被调用

下面是我如何设置挂钩的:

SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHookProcedure,
                 GetModuleHandle(curModule.ModuleName), 0);
有没有人经历过这种情况


我唯一的猜测是,我的钩子函数在一个dll中,而计时器回调来自另一个dll,这与我的问题有关吗???

值得一提的是,我在代码中使用了SetWindowsHookEx的
GetModuleHandle(0)
。我不知道这是否是您的问题--我的代码是单线程的。

为了实现它的价值,我在代码中使用了SetWindowsHookEx的
GetModuleHandle(0)
。我不知道这是否是您的问题——我的代码是单线程的。

您可以在钩子函数中检查前台窗口,然后完全去掉计时器线程。这就是我在TouchCursor中所做的。您可以查看--553行中的钩子函数。

您可以检查钩子函数中的前景窗口,并完全删除计时器线程。这就是我在TouchCursor中所做的。您可以查看--553行中的钩子函数。

钩子回调是在调用SetWindowsHookEx()的同一线程上进行的。这一点的魔力需要该线程泵送一个消息循环。这就是问题所在,计时器回调方法是从线程池线程调用的。它没有泵,它甚至没有足够长的时间来获得钩子回调


调用UI线程或使用同步计时器。或者考虑暂时禁用在钩子回调中所做的任何操作,而不是完全禁用或替换钩子,这当然是最有意义的。

< P>钩子回调是在同一个线程上进行的,称为StWistWoSoOkCEX()。这一点的魔力需要该线程泵送一个消息循环。这就是问题所在,计时器回调方法是从线程池线程调用的。它没有泵,它甚至没有足够长的时间来获得钩子回调



调用UI线程或使用同步计时器。或者考虑暂时禁用在钩子回调中所做的任何操作,而不是完全禁用或替换钩子,这当然是最有意义的。

这将为加载DLL的.exe提供模块句柄。只是澄清一下你的观点。不确定库句柄是否与LL钩子相关。对于其他全局钩子,它是必需的,以便操作系统知道将哪个dll注入其他进程。但是由于LL钩子不会被注入,我不确定这个句柄是否被使用过,而且使用exe的句柄也毫无意义。因为exe不能简单地注入到另一个进程中。因此,我假设它在您的情况下工作,因为LL钩子忽略了它,但是如果它与普通的全局钩子一起工作,我会感到惊讶。这将为加载DLL的.exe提供模块句柄。只是澄清一下你的观点。不确定库句柄是否与LL钩子相关。对于其他全局钩子,它是必需的,以便操作系统知道将哪个dll注入其他进程。但是由于LL钩子不会被注入,我不确定这个句柄是否被使用过,而且使用exe的句柄也毫无意义。因为exe不能简单地注入到另一个进程中。所以我假设它在您的情况下可以工作,因为LL钩子忽略了它,但是如果它与普通的全局钩子一起工作,我会感到惊讶。安装钩子的线程有消息循环吗?低级键盘钩子在其注册的线程上运行,需要进行消息处理。“此钩子在安装它的线程的上下文中调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须具有消息循环。”这与其他在目标线程上运行并需要dll注入的全局钩子不同。@CodeInChaos:Oops——你说得对。我已经删除了我的错误信息。这似乎就是问题所在。安装钩子的线程是否有消息循环?低级键盘钩子在其注册的线程上运行,需要进行消息处理。“此钩子在安装它的线程的上下文中调用。通过向安装钩子的线程发送消息来进行调用。因此,安装钩子的线程必须具有消息循环。”这与其他在目标线程上运行并需要dll注入的全局钩子不同。@CodeInChaos:Oops——你说得对。我已经删除了我的错误信息。这似乎确实是个问题。两个答案?你认为哪一个是对的?你想让我们投票否决他们两个,让他们遭受双重损失吗@大卫:我想无论谁解决了他的问题都是对的。我不想编辑第一个,因为它有一大堆关于GetModuleHandle()的注释。似乎最好加一个新的。这是一种不礼貌的礼节吗?有两个答案是不可取的。通常你只需要编辑你的第一个答案。你可以在一个答案中讨论这两个观点。@David:注意。我确实找过这类问题的常见问题,但什么也找不到。两个答案?你认为哪一个是对的?你愿意吗