WM_SETFOCUS,获取刚刚失去焦点的应用程序
当我的 WTL C++ 应用程序被激活或获得键盘焦点时,我需要确定先前激活/具有焦点的应用程序的窗口句柄。但是,WM_SETFOCUS
和 WM_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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要准确查看正在发送的消息及其参数是什么,一个简单的方法是启动 Spy++ 并将其设置为“日志消息”,同时按 Alt+Tab 切换到另一个窗口。
与您发现的一致,当先前处于活动状态时,
WM_SETFOCUS
和WM_ACTIVATE
的lParam
都将为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 bothWM_SETFOCUS
andWM_ACTIVATE
will beNULL
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 theGetGUIThreadInfo
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.