WinForms:如何确定窗口不再处于活动状态(没有子窗口获得焦点)?

3

我的应用程序使用多个窗口

我希望在应用程序失去焦点(即活动窗口不是应用程序窗口时)隐藏一个特定的窗口 来源

我正在处理主窗体的Deactivate事件。

    private void MainForm_Deactivate(object sender, EventArgs e) 
    {
      Console.WriteLine("deactivate");
      if (GetActiveWindow() == this.Handle) 
      {
        Console.WriteLine("isactive=true");
      }
      else
      {
        Console.WriteLine("isactive=false");
      }
    }

[DllImport("user32.dll")]
static extern IntPtr GetActiveWindow();

输出总是
deactivate
isactive=true

如果我的应用程序中的新窗口获得焦点,或者我点击其他应用程序,我会观察到相同的行为。

当从Deactivate处理程序调用时,我期望GetActiveWindow返回新活动窗口的句柄。但它总是返回我的应用程序窗口的句柄。

这怎么可能?Deactivate事件被处理得“太早”了吗?(在主窗体仍处于活动状态时?)

如何检测我的应用程序失去了焦点(我的应用程序窗口不是活动窗口),另一个应用程序获得了焦点,而不必定时运行GetActiveWindow


我们是在谈论一个 MDI 应用程序吗? - Bobby
不,这不是一个MDI应用程序。 - Marek
2个回答

3

据我所见,GetActiveWindow 获取的是调用线程即应用程序的活动窗口,因此它总是会返回您应用程序的当前窗口。我认为,也许您正在寻找 GetForegroundWindow,它将返回用户当前使用的窗口的句柄。


2
好的观点。顺便提醒一下,GetForegroundWindow 在某些情况下可能会返回 NULL(例如通过单击任务栏按钮切换焦点)。 - Thomas
@Thomas,良好的编程实践是即使您不期望出现NULL,也要检查它,但最好突出显示它(+1)。 - Lazarus

1
我观察到相同的行为(.NET 3.5,Visual Studio 2008)。文档不太清楚:

当窗体失去焦点并不再是活动窗体时发生。

然而,事件名称之间的对比(Activated与Deactivate)表明该事件确实在实际停用之前发生。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接