Windows 窗体窗口启动时失去焦点(位于可执行文件夹后面)
我在 Windows 应用程序启动时遇到一些奇怪的行为,想知道是否有人可以阐明正在发生的事情以及如何解决它。
问题在于应用程序的启动 - 它应该显示一个启动屏幕,然后显示一个登录表单。其代码是:
[STAThread]
static void Main()
{
Application.ThreadException += Application_ThreadException;
MainForm mainForm = null;
Thread splashThread = new Thread(ShowSplash);
try
{
// set up app
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Splash screen
Splash splash = new Splash();
splashThread.Start(splash);
// enable logging
log4net.Config.XmlConfigurator.Configure();
// Create main form
mainForm = new MainForm();
// kill splash
HideForm(splash);
splashThread.Abort();
}
catch (Exception e)
{
splashThread.Abort();
MessageBox.Show(e.Message, "An exception occurred: ", MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(0);
}
// start
Login login = new Login();
login.Show();
if (!mainForm.IsDisposed)
{
Application.Run(mainForm);
}
}
static void ShowSplash(object splash)
{
if (!(splash is Splash))
throw new ArgumentException("Splash screen is of wrong type.");
Splash splashForm = (Splash) splash;
splashForm.ShowDialog();
}
// Thread safe hide form
private delegate void HideFormCallback(Form form);
private static void HideForm(Form form)
{
if (form == null || form.IsDisposed)
return;
if (form.InvokeRequired)
{
HideFormCallback d = HideForm;
form.Invoke(d, new object[] { form });
}
else
{
form.Hide();
}
}
因此,我们使用启动屏幕启动一个新线程,同时设置应用程序的其余部分,然后在显示登录表单之前终止启动屏幕。
我遇到的问题是应用程序启动时登录表单没有焦点。启动画面按预期弹出并消失。登录表单会在任何打开的窗口前面弹出,但没有焦点 - 包含可执行文件(我双击启动)的文件夹即使位于登录表单后面,仍然具有焦点。
如果我注释掉与启动屏幕有关的所有行,则登录表单在出现时将具有焦点。
我的猜测是,当隐藏启动屏幕时,焦点会恢复到可执行文件夹,但我不知道为什么登录表单在启动时没有获得焦点。
在登录表单上调用 .Focus() 返回 null,因此不起作用。
这两种形式都没有 TopMost 或类似的设置。
如果有人对正在发生的事情有任何建议,我们将不胜感激。
I'm getting some strange behaviour in the start-up of a Windows app and wondered if anyone could throw any light on what is happening and how to get around it.
The problem is with the start-up of the app - it should show a splash screen then a login form. The code for this is:
[STAThread]
static void Main()
{
Application.ThreadException += Application_ThreadException;
MainForm mainForm = null;
Thread splashThread = new Thread(ShowSplash);
try
{
// set up app
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Splash screen
Splash splash = new Splash();
splashThread.Start(splash);
// enable logging
log4net.Config.XmlConfigurator.Configure();
// Create main form
mainForm = new MainForm();
// kill splash
HideForm(splash);
splashThread.Abort();
}
catch (Exception e)
{
splashThread.Abort();
MessageBox.Show(e.Message, "An exception occurred: ", MessageBoxButtons.OK, MessageBoxIcon.Error);
Environment.Exit(0);
}
// start
Login login = new Login();
login.Show();
if (!mainForm.IsDisposed)
{
Application.Run(mainForm);
}
}
static void ShowSplash(object splash)
{
if (!(splash is Splash))
throw new ArgumentException("Splash screen is of wrong type.");
Splash splashForm = (Splash) splash;
splashForm.ShowDialog();
}
// Thread safe hide form
private delegate void HideFormCallback(Form form);
private static void HideForm(Form form)
{
if (form == null || form.IsDisposed)
return;
if (form.InvokeRequired)
{
HideFormCallback d = HideForm;
form.Invoke(d, new object[] { form });
}
else
{
form.Hide();
}
}
So, we're starting up a new thread with the splash screen, setting up the rest of the app in the meantime, then killing the splash screen just before showing the login form.
The problem I'm having is that the login form doesn't have focus when the app starts. The splash screen pops up and goes away as expected. The login form pops up in front of any open windows but doesn't have focus - the folder containing the executable (that I double-clicked to launch) still has focus even when it's behind the login form.
If I comment out all the lines to do with the splash screen, the login form has focus when it appears.
My guess would be that the focus reverts back to the executable folder when the splash screen is hidden but I don't know why the login form doesn't get focus when it launches.
Calling .Focus() on the login form returns null so doesn't work.
Neither form have TopMost or such set on them.
If anyone has any suggestions for what's going on, it would be much appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这就是我最终所做的有点棘手的修复:
This is what I've ended up doing as a somewhat hacky fix: