如何监控当前哪个窗口具有键盘焦点

2022-01-12 00:00:00 winapi mfc

有没有办法跟踪哪个窗口当前具有键盘焦点.我可以为每个窗口处理 WM_SETFOCUS 但我想知道是否有另一种更简单的方法(即某处的单个消息处理程序).

Is there a way to track which window currently has keyboard focus. I could handle WM_SETFOCUS for every window but I'm wondering if there's an alternative, simpler method (i.e. a single message handler somewhere).

我可以在 MFC 中使用 OnIdle() 并调用 GetFocus() 但这似乎有点 hacky.

I could use OnIdle() in MFC and call GetFocus() but that seems a little hacky.

推荐答案

所以从你对问题的措辞我推断你想要一个事件处理程序,当焦点在窗口之间切换时调用它.您希望得到通知,而不是轮询.

So from the way you worded the question I'm inferring that you want to have an event handler which is invoked whenever focus switches between windows. You want to be notified, rather than having to poll.

我实际上并不认为从 OnIdle 调用 GetFocus 是一种黑客行为――当然它是轮询,但它是没有副作用的低开销轮询――但如果你真的想跟踪它,Windows Hooks 可能是您的最佳选择.具体来说,您可以安装一个 CBT 挂钩 (WH_CBT) 并监听 HCBT_SETFOCUS 通知.

I actually don't think calling GetFocus from OnIdle is that much of a hack - sure it's polling, but it's low-overhead polling without side effects - but if you really want to track this, Windows Hooks are probably your best choice. Specifically you can install a CBT hook (WH_CBT) and listen for the HCBT_SETFOCUS notification.

当 Windows 即将将焦点设置到任何窗口时,Windows 会使用此挂钩代码调用 WH_CBT 挂钩.在线程特定的钩子的情况下,窗口必须属于线程.如果过滤器函数返回 TRUE,则焦点不会改变.

Windows calls the WH_CBT hook with this hook code when Windows is about to set the focus to any window. In the case of thread-specific hooks, the window must belong to the thread. If the filter function returns TRUE, the focus does not change.

您也可以使用 WH_CALLWNDPROC 挂钩并监听 WM_SETFOCUS 消息.

You could also do with with a WH_CALLWNDPROC hook and listen for the WM_SETFOCUS message.

根据您将其设为全局挂钩还是应用程序本地,您可以跟踪系统上所有窗口的焦点,或仅跟踪您的进程拥有的窗口.

Depending on whether you make it a global hook, or app-local, you can track focus across all windows on the system, or only the windows owned by your process.

相关文章