Windows 窗体窗口启动时失去焦点(位于可执行文件夹后面)

发布于 2024-08-12 02:10:55 字数 2309 浏览 4 评论 0原文

我在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

客…行舟 2024-08-19 02:10:55

这就是我最终所做的有点棘手的修复:

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

    [DllImport("user32")]
    public static extern int SetForegroundWindow(IntPtr hwnd); 

This is what I've ended up doing as a somewhat hacky fix:

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

    [DllImport("user32")]
    public static extern int SetForegroundWindow(IntPtr hwnd); 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文