2011-03-03 164 views
1

当我的WTL C++应用程序被激活或获取键盘焦点时,我需要确定之前激活/关注过的应用程序的窗口句柄。但是,WM_SETFOCUSWM_ACTIVATE消息的窗口句柄(LPARAM)都是NULL(XP,32位)。WM_SETFOCUS,获取刚刚失去焦点的应用程序

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

回答

4

一个简单的方法来查看到底发送了什么消息以及它们的参数是什么,打开Spy ++并将其设置为日志消息,同时将Alt + Tab切换到另一个窗口。

与自己发现相一致,lParam两个WM_SETFOCUSWM_ACTIVATENULL当以前的活动窗口(或窗口被激活)是不是在同一个线程。

按照David的说法,您可能会有更多的运气,WM_ACTIVATEAPP。一旦获得线程标识符,您可以尝试调用GetGUIThreadInfo function来确定该线程的活动窗口。即使活动窗口不属于调用进程,该函数也可以工作。

如果您的应用程序不是一个小型实用程序,而且用户不希望长期保持打开和运行状态,那么考虑到潜在的性能影响,我会尽量避免使用CBT挂钩。不幸的是,跨进程边界的这种交互很困难。

如果您不害怕使用可能会影响未来版本Windows的东西,则可以调查RegisterShellHookWindow function。我不能告诉你很多关于它的信息,从来没有用过它,但是这是一种更简单的方法来获取shell的消息,否则它只会通过安装一个钩子来获得。
它早在Windows 2000之前,但直到XP SP1才被包含在SDK中。据我所知,它仍然存在于Windows Vista和7中。

+0

+1我忘记了'RegisterShellHookWindow'!我在我的应用程序中使用它来检测我的应用程序的.chm帮助文件何时关闭,以便我可以记住它的大小和位置,并在重新启动时恢复它。红色的警告文字是相当令人担忧的,但它似乎在XP到7之间正常工作。 – 2011-03-03 09:43:55