2

我需要一个底层进程来收集有关 Windows 使用的其他应用程序的信息。我怀疑这将使用 WAPI 挂钩来完成。我想做的是让我的程序检测 Windows 何时将焦点从一个程序更改为另一个程序,并告诉我当前哪个程序具有焦点。

首先,我需要一个在 Windows 每次在两个应用程序之间交换焦点时触发的事件。到目前为止,我发现的所有事件都只处理对其正在使用的程序所做的更改,但我需要找到所有焦点更改,即使它位于其他两个程序之间。

我还需要一个让我聚焦窗口的功能。会起作用,还是仅在内部起作用(当前应用程序中的窗口而不是其他程序中的窗口)?

干杯

4

1 回答 1

3

根据您需要焦点变化检测系统的准确程度,您可能能够使用您描述的 API 函数GetForegroundWindow轮询前台窗口的服务(是的,这是系统范围的,而不是特定于进程的)。

然后,您可以使用该函数的句柄来确定哪个进程是当前活动/聚焦的进程。然后检索该进程的焦点元素(子窗口)..

HWND hwnd = GetForegroundWindow();
DWORD remoteThreadId = GetWindowThreadProcessId(hwnd, NULL);
DWORD currentThreadId = GetCurrentThreadId();
AttachThreadInput(rThreadId, curThreadId, TRUE);
HWND focusElement = GetFocus();
AttachThreadInput(rThreadId, curThreadId, FALSE);

继续这样做..并做任何你需要做的事情focusElement

更新

好吧,显然,正如@Kenneth K. 在评论中发布的那样,您可以挂钩一个全局EVENT_SYSTEM_FOREGROUND事件,以便在前台(聚焦)窗口更改时通知您的应用程序。这样您就不需要连续循环来检测这些变化。

EVENT_SYSTEM_FOREGROUND = 3;
WINEVENT_OUTOFCONTEXT = 0;

您可以按照此答案中的示例查看如何挂钩此事件并获取通知。然后,每当前台(聚焦)窗口发生更改时,您可以使用SetWindowsHookEx函数挂钩该窗口的消息循环并查看该窗口的焦点更改事件。

另一种选择是查阅MSDN 上的系统事件列表,看看是否有一个可以代替EVENT_SYSTEM_FOREGROUND使用,或者与它一起用于检测控制级焦点事件。也许EVENT_OBJECT_FOCUS可能有用。

如果这仍然不清楚,请告诉我。

于 2013-03-08T21:17:07.120 回答