不激活子窗口

时间:2017-08-28 17:00:42

标签: windows winapi windows-7

我有一个普通的窗口,我想添加一个按钮,当它处于非活动状态时可以在我的窗口中按下,这不会从当前活动的窗口中窃取焦点。

示例:触摸Windows 8 / 8.1 / 10系统任务栏中的键盘按钮,这一个:

enter image description here

请注意,单击此按钮时,活动应用程序仍处于活动状态,但单击其空白区域时焦点将转到任务栏。

经典解决方案:

  • 要使整个顶级窗口不可激活,可以使用WS_EX_NOACTIVATE ex-style。不幸的是,这种风格会导致顶级窗口出现很多问题,并且无法应用于子窗口。

  • 通常建议的方法是在单击控件的情况下侦听WM_MOUSEACTIVATE消息并回答MA_NOACTIVATE。这是有效的,但只是部分:在单击期间不会激活窗口,但先前活动的窗口会失去活动状态,GetForegroundWindow返回0.这可以通过记住最后一个活动窗口(通过定期轮询,或者通过监视EVENT_SYSTEM_FOREGROUND或HSHELL_WINDOWACTIVATED / HSHELL_RUDEAPPACTIVATED),并强制恢复它。实际上很多头痛。

1 个答案:

答案 0 :(得分:1)

<强> Win7的路

从Windows 7开始,有一个新的未记录的 API函数SetChildWindowNoActivate,在user32.dll中有ordinal 2005。它可以像这样声明(Delphi风格):

function SetChildWindowNoActivate(ChildWnd: HWND): BOOL; stdcall;
  external 'user32.dll' index 2005;

此功能在Windows 8 / 8.1 / 10中用于制作触摸键盘,虚拟触控板和语言切换器等无激活按钮。

下面是一个示例应用程序的屏幕截图,其中包含一个推送的无激活按钮和一个活动的资源管理器窗口:

enter image description here