WM_SETFOCUS,获取刚刚失去焦点的应用程序

发布于 2024-10-19 23:17:43 字数 235 浏览 1 评论 0原文

当我的 WTL C++ 应用程序被激活或获得键盘焦点时,我需要确定先前激活/具有焦点的应用程序的窗口句柄。但是,WM_SETFOCUSWM_ACTIVATE 消息的窗口句柄 (LPARAM) 均为 NULL(XP,32 位)。

当我的应用程序被激活时,如何确定刚刚失去焦点的应用程序?有没有简单的方法可以做到这一点,或者我需要滚动一个特殊的 CBT 钩子?

When my WTL C++ application is activated or gets the keyboard focus I need to determine the window handle of the application that was previously activated/had focus. However, the window handles (LPARAM) of both the WM_SETFOCUS and WM_ACTIVATE messages are both NULL (XP, 32 bit).

How can I determine the application that just lost focus when my application is activated? Is there a simple way to do this or will I need to roll a special CBT hook?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁吢 2024-10-26 23:17:43

要准确查看正在发送的消息及其参数是什么,一个简单的方法是启动 Spy++ 并将其设置为“日志消息”,同时按 Alt+Tab 切换到另一个窗口。

与您发现的一致,当先前处于活动状态时,WM_SETFOCUSWM_ACTIVATElParam 都将为 NULL窗口(或活动窗口)不在同一线程中。

使用 WM_ACTIVATEAPP 可能会更幸运,正如大卫建议的那样。获取线程标识符后,您可以尝试调用 GetGUIThreadInfo 函数 确定该线程的活动窗口。即使活动窗口不属于调用进程,此函数也将起作用。

如果您的应用程序不是一个小型实用程序,并且用户预计不会长时间保持打开和运行,那么考虑到潜在的性能影响,如果可能的话,我会避免使用 CBT 挂钩。不幸的是,像这样的跨进程边界的交互是很困难的。

如果您不担心使用可能会破坏 Windows 未来版本的功能,您可以研究 RegisterShellHookWindow函数。我不能告诉你太多关于它的信息,因为我自己从未使用过它,但这是一种获取 shell 消息的更简单的方法,否则你只能通过安装钩子来接收。
它早在 Windows 2000 就出现了,但直到 XP SP1 才包含在 SDK 中。据我所知,它仍然存在于 Windows Vista 和 7 中。

An easy way to see exactly what messages are being sent and what their parameters are is to fire up Spy++ and set it to Log Messages while you Alt+Tab to another window.

Consistent with what you've discovered, the lParam for both WM_SETFOCUS and WM_ACTIVATE will be NULL when the previously active window (or the window being active) is not in the same thread.

You might have more luck with WM_ACTIVATEAPP, as David suggested. Once you get the thread identifier, you can try calling the GetGUIThreadInfo function to determine the active window for that thread. This function will work even if the active window is not owned by the calling process.

If your app is anything other than a small utility that the user is not expected to keep open and running for very long, I would shy away from using a CBT hook if at all possible, given the potential performance implications. Unfortunately, interaction like this across process boundaries is difficult.

If you're not afraid of using things that may break with future versions of Windows, you could investigate the RegisterShellHookWindow function. I can't tell you much about it, having never used it myself, but it's an easier way to get the shell messages you would otherwise only receive by installing a hook.
It was around as far back as Windows 2000, but wasn't included in the SDK until XP SP1. It still exists in Windows Vista and 7, as far as I can tell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文