【问题标题】:Is it possible to create a sub window which will not deactivate the parent?是否可以创建一个不会停用父窗口的子窗口?
【发布时间】:2011-02-22 01:25:19
【问题描述】:

通常在创建子窗口(WS_POPUP)时,子窗口将变为激活状态,而父窗口将变为非激活状态。但是,对于菜单,两者都保持活动状态。至少我假设菜单是活动的,它至少有焦点。

示例:单击记事本中的文件菜单,出现菜单,但记事本窗口仍然处于活动状态。

是否可以使用窗口样式或响应特定消息来反映此行为?

谢谢

另一个例子:组合框似乎显示了一个子窗口,但并未停用该窗口。您可以单击该子窗口,同时仍保持激活主窗口。关于如何获取该窗口的类/样式的任何想法?

【问题讨论】:

  • OSK.EXE (onscreen-keyboard) 可以做到这一点——尽管是全球性的——你可以用 spy++ 戳它
  • 绝对喜欢这个主意。但是,当我尝试它时,它似乎只是继续激活前一个窗口(即:顶部窗口仍然略微失去激活)。我正在尝试创建一些感觉就像菜单(但看起来完全不同)的东西,即使是短暂的激活丢失也感觉不对。

标签: winapi menu createwindow


【解决方案1】:

组合框中的下拉列表有点 hack,它既是弹出窗口又是子窗口,我不推荐这种方法(未记录的样式组合和 IIRC,这样做有点错误一个“正常”的浮动窗口/工具栏)

这让您有两个选择:

  • WS_EX_NOACTIVATE(主窗口将保持活动状态,浮动窗口不活动)
  • Handle activate messages(两个窗口看起来都处于活动状态)

【讨论】:

  • 您的链接看起来很吸引人。昨晚我正在考虑使用工具窗口方法,但没有意识到他们的激活不是免费的。
  • 您的链接正是我所需要的。非常感谢。
【解决方案2】:

我很惊讶创建一个新的弹出窗口会激活它。通常您需要致电SetActiveWindow。不过请查看WM_ACTIVATEWM_NCACTIVATE,了解如何阻止窗口被停用。

【讨论】:

  • 我很可能在做一个 SW_SHOW,而不是一个 SW_SHOWNOACTIVATE。但是,如果你不介意的话,我还有一些其他的问题。您是否可以在未激活的窗口中获得焦点(即:如果用户开始使用键盘,我希望向上/向下工作就像在普通菜单中一样)?或者您是否可以禁止点击激活?
  • 我不能说我已经做到了,但我对结果如何很感兴趣。尝试使用 Spy++ 并在显示菜单时检查消息。
【解决方案3】:

很多人忽略的一个事实是,windows 没有单独的窗口管理器组件:- 大多数窗口管理职责由每个窗口执行- 通常在 DefWindowProc 中。

大多数窗口定位和激活/取消激活都是通过调用 SetWindowPos 完成的,它总是发送 WM_WINDOWPOSCHANGING 消息,让窗口对发生的事情有最终决定权。

DefWindowProc 也会激活它自己的窗口以响应鼠标点击等等。

所有这一切的结果是,很有可能创建从不接受激活的窗口 - 它确实需要广泛了解可能导致激活的消息和情况。

最后我可以说,为远程调试配置调试设置非常方便 - 这样您就可以在不影响系统激活状态的情况下与调试器交互 - 并因此在 WM_ACTIVATE 问题窗口中放置断点处理程序并简单地调试任何导致意外激活的情况。

如果您也想处理键盘焦点,它可能会更棘手 - 通常焦点会分配给激活的窗口 - 但通常是 DefWindowProc 负责分配两者。我只是认为有一个窗口很危险,显然仍然处于激活状态,而另一个窗口则有焦点。这会极大地混淆任何辅助软件。

我很想执行消息循环级别的消息挂钩 - 类似于 IsDialogMessage - 以过滤用于弹出窗口的击键。

【讨论】:

    【解决方案4】:

    如果您使用 WS_EX_NOACTIVATE 创建弹出窗口,用户输入将不会激活它(您仍然可以通过编程方式激活它),因此您的主应用程序窗口仍将保持活动状态。

    【讨论】:

    • 主应用程序窗口仍将处于非活动状态(除非您还处理 WM_NCACTIVATE 以防止这种情况发生)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 2021-09-10
    • 1970-01-01
    • 2011-07-08
    • 2011-09-03
    相关资源
    最近更新 更多