模态对话框无法获得焦点

时间:2012-03-28 12:02:01

标签: c# winforms

我正在处理与启动了启动画面的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:好吧,我刚刚删除了启动画面,现在登录表单获得了焦点。更换启动屏幕会重新引入错误。但是在我尝试打开登录表单之前,我已经放入代码以确保启动屏幕处理 - 而不是关闭 -

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

4 个答案:

答案 0 :(得分:5)

  

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

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

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

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

答案 1 :(得分:2)

我之前遇到过类似问题,问题是由于启动画面关闭不当造成的。我怀疑焦点可能在那种形式上(尽管不确定)。

  1. 确保正确卸载/关闭启动画面
  2. 正确卸载启动画面后显示
  3. 登录界面
  4. 登录表单显示为模式,用于指示执行指针等待下一次用户交互

答案 2 :(得分:1)

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

答案 3 :(得分:1)

如果你提出这个可能会是一个解决方案:

this.Activate();

或者这个:

SetForegroundWindow(this.Handle.ToInt32());

在表单的load事件中。

如果这不起作用,请尝试使用定时器,该定时器会在一段时间后激活此代码。