究竟是WM_ACTIVATE发送了哪些场合?

时间:2010-01-19 10:36:03

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

我正在尝试调试一个巨大的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(),我不会对可以切换窗口的键盘做任何事情。

使用WA_ACTIVE发送WM_ACTIVATE还有哪些其他原因?

2 个答案:

答案 0 :(得分:4)

您的问题是由SetForegroundWindow()引起的。它具有适当的对策,可防止进程在其他应用程序中积极工作时将窗口推入用户的脸部。

当第二个进程创建窗口并隐式尝试使用前景时,SetForegroundWindow()正在发生。 (当你写“带到前线”时,你也说了很多。)

第一个应用程序应该调用AllowSetForegroundWindow()来说“没关系,该窗口可以从我那里进行前台激活。”

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

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

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

答案 1 :(得分:1)

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

如果您执行ShowWindow(SW_SHOW),则会激活该窗口(改为使用SW_SHOWNA

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

最后,如果您创建一个带有模板的窗口(CDialog),则窗口始终处于激活状态。