【问题标题】:On which occasions exactly is WM_ACTIVATE sent?WM_ACTIVATE 到底是在什么情况下发送的?
【发布时间】:2010-01-19 10:36:03
【问题描述】:

我正在尝试调试一个巨大的 Win32 GUI 应用程序(我有完整的源代码),它分为几个进程。问题如下:在一个进程中,我有一个带有列表框的对话框,当我双击列表框中的一个项目时,另一个进程启动,该进程创建了自己的窗口,该窗口被带到前面并覆盖了初始对话框。如果我做了一些操作(我还不能完全解释,因为我还没有完全理解它们),就会强制初始对话框开始在任务栏中闪烁。

我尝试了 Microsoft Spy++,发现每当我执行该操作时,WM_ACTIVATE 都会发送到对话框,大多数情况下它具有以下参数:

fActive: WA_INACTIVE fMinimized:False hwndPrevious:(null)

在这些情况下,对话框不会开始闪烁。但有时参数是

fActive: WA_ACTIVE fMinimized:False hwndPrevious:(null)

这恰好对应于对话框闪烁。

MSDN says WM_ACTIVATE 与 WA_ACTIVE 一起发送时,通过鼠标单击以外的其他方法激活窗口(例如,通过调用 SetActiveWindow 函数或使用键盘界面选择窗口) .

现在,在应用程序代码中,SetActiveWindow() 从未被调用,并且我不会对可以切换窗口的键盘进行任何操作。

WM_ACTIVATE 与 WA_ACTIVE 一起发送还有哪些其他可能的原因?

【问题讨论】:

    标签: user-interface winapi visual-c++


    【解决方案1】:

    您的问题是由SetForegroundWindow() 引起的。它有适当的对策,可以防止进程在用户积极使用另一个应用程序时将窗口推到用户面前。

    SetForegroundWindow() 发生在第二个进程创建其窗口并隐式尝试使用它时。 (你在写“带到前台”时也说了这么多。)

    第一个应用程序应该调用AllowSetForegroundWindow() 说“没关系,允许该窗口从我这里获取前台激活。”

    请注意,如果您这样做,那么用户可能会遇到这种情况:

    • 用户点击列表框项。
    • 第二个进程启动缓慢。
    • 用户单击第一个应用程序中的其他内容。 (失去耐心。)
    • 第二个进程从第一个应用程序中窃取前台。 (用户很沮丧,因为他正在做其他事情。)

    这就是导致当前代码闪烁的情况。窗口管理器检测到用户已放弃等待第二个进程并开始对第一个进程执行其他操作,因此当第二个进程最终尝试窃取前台时,它会阻止第二个进程。

    【讨论】:

      【解决方案2】:

      如果您创建一个WS_VISIBLE 样式的窗口,该窗口将在创建时被激活。

      如果您执行ShowWindow(SW_SHOW),它将激活窗口(改用SW_SHOWNA

      如果您在没有SWP_NOACTIVATE 标志的情况下执行SetWindowPos,则会激活该窗口。

      最后,如果你用模板(CDialog)创建一个窗口,这个窗口总是被激活的。

      【讨论】:

      • 关于我所说的一点点说明,如果是对话框,您可以阻止它被激活,您需要在 OnInitDialog 中返回 FALSE 并且必须在没有 WS_VISIBLE 样式的情况下无模式地创建对话框并且你用 ShowWindow(SW_SHOWNA) 显示它
      猜你喜欢
      • 2020-06-06
      • 2012-07-03
      • 1970-01-01
      • 2011-03-05
      • 2013-04-23
      • 1970-01-01
      • 2020-02-19
      • 2014-12-22
      • 2016-05-19
      相关资源
      最近更新 更多