1

我在启动 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 或类似的设置。

如果有人对正在发生的事情有任何建议,将不胜感激。

4

1 回答 1

4

这就是我最终做的一个有点hacky的修复:

    void LoginView_Shown(object sender, EventArgs e)
    {
        SetForegroundWindow(Handle);
        this.BringToFront();
        Activate();           
    }

    [DllImport("user32")]
    public static extern int SetForegroundWindow(IntPtr hwnd); 
于 2009-11-17T14:11:22.700 回答