【问题标题】:Modal dialog doesn't get focus模态对话框没有获得焦点
【发布时间】:2012-04-12 00:27:40
【问题描述】:

我正在处理与 C# WinForms 应用程序相关的错误,该应用程序以初始屏幕启动,然后关闭初始屏幕并打开登录表单。在某些计算机上一切正常。在其他情况下,登录表单会出现,但标题栏会闪烁,几次闪烁后,它会完全失去焦点。光标还在“用户名”文本框中闪烁,但是应用没有焦点,开始输入时什么也没有发生,这对用户来说很烦。

运行什么操作系统似乎没有区别(我们已经尝试过 Windows 7 和 Server 2008),并且我们一直特别注意在启动应用程序后不要有任何键盘或鼠标输入。

现在 - 有没有人知道是什么导致应用失去焦点?
或者,您将如何调试此问题?我们无法在 Visual Studio 调试环境中复制该问题,但这并不完全让我感到惊讶,因为我猜这是编译后的应用程序如何与操作系统交互的问题......还是我错了?

编辑#1:我认为这是由@vinodpthmn 解决的,通过确保在登录表单出现之前正确关闭启动屏幕,但这似乎没有帮助。所以我创建了一个记录器来跟踪所有事件和线程,并发现了以下有趣的日志条目:

Thread 01 - 2012/03/29 12:51:09.693 - Show splash screen
Thread 01 - 2012/03/29 12:51:20.350 - Splash screen closed
Thread 01 - 2012/03/29 12:51:20.490 - Login Form Activated
Thread 01 - 2012/03/29 12:51:20.522 - Login Form Load
Thread 01 - 2012/03/29 12:51:25.694 - Login Form deactivated
Thread 01 - 2012/03/29 12:51:25.694 - Active form =
Thread 01 - 2012/03/29 12:51:25.694 - Active app =

显示活动表单和应用程序的最后几行分别显示Form.ActiveForm 和 Windows 中当前活动的应用程序(此代码为 here)。而且它们都是空的/空的。就是这样,即使在登录表单加载中我按照@memetolsen 的建议调用Activate()SetForegroundWindow()。登录表单甚至从未获得焦点!

有什么想法吗?

编辑#2:好吧,我刚刚消除了初始屏幕,现在登录表单获得焦点。更换启动画面会重新引入错误。但是我已经输入了代码以确保在我尝试打开登录表单之前 disposed 启动屏幕 - 而不仅仅是关闭。

使用Application.Run(frmSplash) 打开启动画面会有所不同吗?

【问题讨论】:

  • 事后附加调试器。
  • 启动画面是否已处理,或者是否仍会干扰主 UI 消息线程。
  • 当另一个窗口尝试激活时,您会在模式窗口中获得闪烁的标题。

标签: c# winforms


【解决方案1】:

我建议你设置remote debugging。这将使您能够从您的开发机器远程调试应用程序。

【讨论】:

    【解决方案2】:

    如果你这样说可能会是一个解决方案:

    this.Activate();
    

    或者这个:

    SetForegroundWindow(this.Handle.ToInt32());
    

    在表单的加载事件中。

    如果这不起作用,请尝试使用一个计时器,该计时器会在一段时间后生成此代码。

    【讨论】:

      【解决方案3】:

      我之前遇到过类似的问题,问题是由于启动屏幕关闭不当造成的。我怀疑重点可能在那个表格上(虽然不确定)。

      1. 确保正确卸载/关闭初始屏幕表单
      2. 正确卸载初始屏幕后显示登录屏幕
      3. 登录表单显示为模态以指示执行指针等待下一次用户交互

      【讨论】:

        【解决方案4】:

        使用 Application.Run(frmSplash) 打开启动画面会有所不同

        当然,这样做可以保证你会遇到这种问题。造成此问题的原因是您有一瞬间的 no 窗口可以接收焦点。初始屏幕消失了,您的主窗口仍然需要几毫秒才能创建并显示。这会强制 Windows 找到另一个窗口来获得焦点。由于它不能是您的窗口,它将选择另一个应用程序的窗口。您的主窗口出现时将没有焦点。

        我不清楚窗口管理器使用的确切规则,这种焦点丢失并不总是发生。我猜这与时间有关。

        使用框架中已经内置的对启动画面的出色且无故障的支持来解决您的问题。您可以在this answer 中找到使用它的代码。如果您不想使用它,请重新编写代码以确保在关闭初始屏幕之前显示主窗口。

        【讨论】:

        • 谢谢!我为启动画面的Closing 事件添加了延迟,现在登录表单获得焦点!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-29
        • 1970-01-01
        • 2016-03-06
        相关资源
        最近更新 更多