WinForms:如何确定窗口是不是不再活动(没有子窗口有焦点)?

Posted

技术标签:

【中文标题】WinForms:如何确定窗口是不是不再活动(没有子窗口有焦点)?【英文标题】:WinForms: How to determine if window is no longer active (no child window has focus)?WinForms:如何确定窗口是否不再活动(没有子窗口有焦点)? 【发布时间】:2011-01-31 19:36:52 【问题描述】:

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

我想隐藏一个特定窗口以防应用程序失去焦点(当活动窗口不是应用程序窗口时)source

我正在处理我的主窗体的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

如果我的应用程序中的一个新窗口获得焦点,并且如果我点击另一个应用程序,我观察到了相同的行为。

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

这怎么可能? Deactivate 事件是否“过早”处理? (而主窗体仍然处于活动状态?)。

如何检测我的应用程序失去焦点(我的应用程序窗口不是活动窗口)并且另一个应用程序在没有在计时器上运行 GetActiveWindow 的情况下获得它?

【问题讨论】:

我们是在谈论 MDI 应用程序吗? 不,这不是 MDI 应用程序 【参考方案1】:

我观察到相同的行为(.NET 3.5,Visual Studio 2008)。文档很模糊:

当表单失去焦点并且不再是活动表单时发生。

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

【讨论】:

【参考方案2】:

据我所知,GetActiveWindow 是调用线程的活动窗口,即您的应用程序,因此它总是会返回您应用程序的当前窗口。我想也许您正在寻找 GetForegroundWindow 它将句柄返回到用户当前处于活动状态的窗口。

【讨论】:

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

以上是关于WinForms:如何确定窗口是不是不再活动(没有子窗口有焦点)?的主要内容,如果未能解决你的问题,请参考以下文章

如何抑制运行 C# Winforms 应用程序时弹出的黑壳?

确定何时移动 WPF 窗口

如何在每个使用桌面分辨率的右下角放置一个窗口(Winforms)

如何使复选框确定是否应显示活动

WinForms:无法最大化模糊窗口

在 VS 2010 的 Winforms 项目中添加 WPF 窗口