【问题标题】:No-activate child windows不激活子窗口
【发布时间】:2017-08-28 17:00:42
【问题描述】:

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

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

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

经典解决方案:

  • 要使整个顶级窗口不可激活,可以使用 WS_EX_NOACTIVATE ex 样式。不幸的是,这种样式在顶级窗口中会引起很多问题,并且不能应用于子窗口。

  • 通常推荐的方法是收听 WM_MOUSEACTIVATE 消息并回答 MA_NOACTIVATE,以防单击控件。这有效,但仅部分有效:在单击期间不会激活窗口,但先前活动的窗口会失去活动状态,并且 GetForegroundWindow 返回 0。这可以通过记住最后一个活动窗口来解决(通过定期轮询,或通过监视 EVENT_SYSTEM_FOREGROUND 或 HSHELL_WINDOWACTIVATED / HSHELL_RUDEAPPACTIVATED),并通过强制恢复它。其实很头疼。

【问题讨论】:

  • 你确定WM_MOUSEACTIVATE?这与我的经验不符。
  • 单击按钮需要 SetCapture() 才能工作。 MSDN 文档指出此功能仅适用于前台窗口。除了与 MouseUp 通知一起笨拙外,样板文件是让此类键盘弹出窗口使用子控件。它只需要看起来像一个按钮,并不难画。
  • 一个问题应该有一个问题。

标签: windows winapi windows-7


【解决方案1】:

Win7 方式:

从 Windows 7 开始,有一个新的 undocumented API 函数 SetChildWindowNoActivate,user32.dll 中的序号为 2005。可以这样声明(Delphi 风格):

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

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

这是一个示例应用程序的屏幕截图,上面有一个按下的非激活按钮和一个活动的资源管理器窗口:

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-06
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多