Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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_Input - Fatal编程技术网

C++ 有没有办法找出哪个线程接收了最后一次输入?

C++ 有没有办法找出哪个线程接收了最后一次输入?,c++,c,winapi,input,C++,C,Winapi,Input,我目前正在诊断一个窗口激活问题,其中对的调用失败,尽管我相信它是从前台线程调用的。当输入来自触摸式数字化仪时,问题是可再现的 有没有办法找出哪个线程接收了最后一次输入?我试着打电话给他从他那儿回来的那个把手。然而,这似乎返回了过时的信息,就在窗口1)的输入激活之后 由于这只是用于诊断问题,如果公共接口不可用,我很乐意使用未记录的接口解决方案。在这种情况下,目标平台是64位Windows 7 1) GetForegroundWindow返回相同的句柄,无论输入来自触摸式数字化仪还是定点设备。当输

我目前正在诊断一个窗口激活问题,其中对的调用失败,尽管我相信它是从前台线程调用的。当输入来自触摸式数字化仪时,问题是可再现的

有没有办法找出哪个线程接收了最后一次输入?我试着打电话给他从他那儿回来的那个把手。然而,这似乎返回了过时的信息,就在窗口1)的输入激活之后

由于这只是用于诊断问题,如果公共接口不可用,我很乐意使用未记录的接口解决方案。在这种情况下,目标平台是64位Windows 7


1)
GetForegroundWindow
返回相同的句柄,无论输入来自触摸式数字化仪还是定点设备。当输入来自定点设备时,对
SetForegroundWindow
的后续调用成功,但触摸输入失败

由于这只是用于诊断问题,如果公共接口不可用,我很乐意使用未记录的接口解决方案

您可以尝试使用SetWindowsHookEx安装WH_GETMESSAGE的系统范围钩子,并监视诸如WM_SETFOREGROUND之类的有趣消息。在调用原始版本之前记录有趣的内容


另一个想法是使用或钩住SetForeGroundWindowAPI。正如您在这里看到的,使用mhook看起来非常简单。

GetWindowThreadProcessId
不会返回上次收到窗口输入的线程。它告诉您是哪个踏板创建了窗口,因此应该处理输入

您必须知道Windows输入通过消息工作。这些消息被传递到线程消息队列。这直接解释了为什么每个窗口都有一个关联的线程:这就是消息传递到的线程

在普通应用程序中,所有窗口都是由单个“前台”或“UI”线程创建的。因此,问题“哪个线程接收了最后一个输入”总是“前台线程”。后台线程根本不接收窗口消息

很少有应用程序在多个线程上创建多个窗口,即使这是允许的。在这些情况下,两个线程可以同时接收消息,这使得“最后一次输入”的概念无效。在这些情况下,每个线程都有自己的“最后一次输入”

回到您声明的问题,
setforegroundindow
没有记录在案的线程限制。特别是,不限制必须从前台线程调用它。事实上,文档说明它可以是另一个进程(当然也就是另一个线程)


您特别提到了“最后一次输入”,但限制仅提到在流程上下文中:“只有当……流程接收到最后一次输入事件时,流程才能设置前台窗口”。

这并没有回答所问的问题,而是解决了导致此问题的根本问题:

API对线程可以成功调用它施加了一些限制。先决条件之一是调用线程的

进程收到最后一个输入事件

不幸的是,在Windows7上,这不包括触摸输入。进程没有资格调用
setforegroundindow
,以响应
WM\u TOUCH
。直到系统合成了相应的兼容鼠标输入事件,流程才最终获得前台激活权限


这已经改变了,从Windows 8开始,触摸输入被视为一级输入,调用
setforegroundindow
成功响应
WM\u touch
消息。

你能用Spy++查看哪个窗口接收到最后一条鼠标消息吗?@JonathanPotter:Spy++只能监视单个窗口的消息,除非我没有找到您想要的特定功能。在调用SetForeGroundIndow API之前,您是否在代码中调用了AllowSetForeGroundIndow(ASFW_ANY)?我们遇到了类似的问题,打电话给AllowSetForeGrounddow解决了这个问题。[注意:我们的问题并不是针对触摸输入]@PraveenRaoJoginapally:我没有打电话,也不知道这有什么帮助。此API仅将调用
SetForegroundWindow
的权限传递给另一个窗口/线程。它只能从一个线程调用,该线程已经有资格调用
SetForegroundWindow
本身。我的问题是,调用
setforegroundindow
失败,调用
allowsetforegroundindow
也会失败。Spy++有一个选项可以监视系统中的所有窗口。它位于附加窗口部分(底部)的消息选项对话框中。每当消息离开应用程序消息队列时,就会调用
WH\u GETMESSAGE
hook。当消息进入输入队列时,我试图查找有关消息的信息。至于hooking
setforegroundindow
:我并没有试图阻止任何人调用它。这对我来说是失败的,尽管我相信我有资格使用它。我从窗口的线程调用它,以响应触摸/鼠标输入,它显示了鼠标输入所需的行为,而不是触摸输入。Windows中的输入通过输入队列而不是消息队列工作。输入事件进入全局硬件输入队列,在那里它们被原始输入线程提取,然后被处理,传递到低级输入挂钩,最后被签署到相应应用程序的输入队列。然后,拥有该队列线程的进程有资格调用
SetForegroundWindow
。记录在案的限制是真实限制的浓缩、简化版本,它们显然是错误的。每次出现的进程都应该读取线程或输入附加的线程组。