启动画面不会将焦点返回到主窗体

发布于 2024-09-26 05:11:23 字数 3407 浏览 2 评论 0原文

我大家。目前,我在使用启动画面时注意力不集中。我使用的是 VS2008,带有 .NET Framework 2.0。另外,我已将我的项目与 VisualBasic.dll 链接起来,因为我使用 ApplicationServices 来管理我的单实例应用程序和启动屏幕。

这是我尝试调试的简化代码片段。

namespace MyProject
{
    public class Bootstrap
    {
        /// <summary>
        /// Main entry point of the application. It creates a default 
        /// Configuration bean and then creates and show the MDI
        /// Container.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            // Creates a new App that manages the Single Instance background work
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            App myApp = new App();
            myApp.Run(args);
        }
    }

    public class App : WindowsFormsApplicationBase
    {
        public App()
            : base()
        {
            // Make this a single-instance application
            this.IsSingleInstance = true;
            this.EnableVisualStyles = true;

            // There are some other things available in the VB application model, for
            // instance the shutdown style:
            this.ShutdownStyle = Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses;

            // Add StartupNextInstance handler
            this.StartupNextInstance += new StartupNextInstanceEventHandler(this.SIApp_StartupNextInstance);
        }

        protected override void OnCreateSplashScreen()
        {
            this.SplashScreen = new MyMainForm();
            this.SplashScreen.StartPosition = FormStartPosition.CenterScreen;
        }
        protected override void OnCreateMainForm()
        {
            // Do your initialization here
            //...
            System.Threading.Thread.Sleep(5000);  // Test
            // Then create the main form, the splash screen will automatically close
            this.MainForm = new Form1();
        }
        /// <summary>
        /// This is called for additional instances. The application model will call this 
        /// function, and terminate the additional instance when this returns.
        /// </summary>
        /// <param name="eventArgs"></param>
        protected void SIApp_StartupNextInstance(object sender,
            StartupNextInstanceEventArgs eventArgs)
        {
            // Copy the arguments to a string array
            string[] args = new string[eventArgs.CommandLine.Count];
            eventArgs.CommandLine.CopyTo(args, 0);

            // Create an argument array for the Invoke method
            object[] parameters = new object[2];
            parameters[0] = this.MainForm;
            parameters[1] = args;

            // Need to use invoke to b/c this is being called from another thread.
            this.MainForm.Invoke(new MyMainForm.ProcessParametersDelegate(
                ((MyMainForm)this.MainForm).ProcessParameters),
                parameters);
        }
    }
}

现在,发生的情况是,当我启动应用程序时,启动屏幕按预期显示,但是当它被销毁时,它不会将焦点返回到主窗体(测试中的 Form1)。 MainForm 只是在任务栏中闪烁橙色。如果我从 IDE (VS2008) 启动应用程序,焦点工作得很好。我用的是XP专业版。此外,主窗体并不位于其他所有窗口之上。如果我注释掉 OnCreateSplashScreen() 方法,应用程序将正常获得焦点。

为了测试正常执行,我使用 VS 命令提示符来启动我的应用程序。我正在使用我的项目的发布版本。

有什么想法吗?

编辑: 我还处理 StartUpNextInstance 事件以将命令行参数发送到主窗体。出于测试目的,此处将其删除。

编辑:添加了更多代码。现在你已经了解了我的引导程序的全部内容。

I everyone. I currently have a problem with my focus when using a splash screen. I am using VS2008, with .NET framework 2.0. Also, I have linked my project with the VisualBasic.dll since I use the ApplicationServices to manage my single instance app and splash screen.

Here is a code snippet simplified of what I tried debugging.

namespace MyProject
{
    public class Bootstrap
    {
        /// <summary>
        /// Main entry point of the application. It creates a default 
        /// Configuration bean and then creates and show the MDI
        /// Container.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            // Creates a new App that manages the Single Instance background work
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            App myApp = new App();
            myApp.Run(args);
        }
    }

    public class App : WindowsFormsApplicationBase
    {
        public App()
            : base()
        {
            // Make this a single-instance application
            this.IsSingleInstance = true;
            this.EnableVisualStyles = true;

            // There are some other things available in the VB application model, for
            // instance the shutdown style:
            this.ShutdownStyle = Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses;

            // Add StartupNextInstance handler
            this.StartupNextInstance += new StartupNextInstanceEventHandler(this.SIApp_StartupNextInstance);
        }

        protected override void OnCreateSplashScreen()
        {
            this.SplashScreen = new MyMainForm();
            this.SplashScreen.StartPosition = FormStartPosition.CenterScreen;
        }
        protected override void OnCreateMainForm()
        {
            // Do your initialization here
            //...
            System.Threading.Thread.Sleep(5000);  // Test
            // Then create the main form, the splash screen will automatically close
            this.MainForm = new Form1();
        }
        /// <summary>
        /// This is called for additional instances. The application model will call this 
        /// function, and terminate the additional instance when this returns.
        /// </summary>
        /// <param name="eventArgs"></param>
        protected void SIApp_StartupNextInstance(object sender,
            StartupNextInstanceEventArgs eventArgs)
        {
            // Copy the arguments to a string array
            string[] args = new string[eventArgs.CommandLine.Count];
            eventArgs.CommandLine.CopyTo(args, 0);

            // Create an argument array for the Invoke method
            object[] parameters = new object[2];
            parameters[0] = this.MainForm;
            parameters[1] = args;

            // Need to use invoke to b/c this is being called from another thread.
            this.MainForm.Invoke(new MyMainForm.ProcessParametersDelegate(
                ((MyMainForm)this.MainForm).ProcessParameters),
                parameters);
        }
    }
}

Now, what happens is that, when I start the application, the Splash Screen shows as expected, but when it is destroyed, it does not return the focus to the main form (Form1 in the test). The MainForm simply flashes orange in the taskbar. If I launch the application from the IDE (VS2008), focus works just fine. I am using XP Pro. Also, the main form is not on top of every other windows. If I comment out the OnCreateSplashScreen() method, the application gets focus normally.

To test normal execution, I am using the VS Command Prompt to launch my application. I am using the Release version of my project.

Any ideas?

Edit:
I also handle the StartUpNextInstance event to send my command-line arguments to my main form. For test purposes, it was removed here.

Edit: Added a bit more code. Now you have the full extent of my bootstrap.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(8

GRAY°灰色天空 2024-10-03 05:11:23

问题不详细。

1)SplashScreen和应用程序的主窗体之间有什么关系?

2)SplashScreen如何自动关闭?

我确信这里的问题是主窗体已经开始在后台加载,而 SplashScreen 尚未关闭。由于时机不好,主窗体在后台加载,而 SplashScreen 卸载......因此任务栏中会闪烁。

使它们以串行控制的方式出现。有很多方法。我无法确切地建议如何,因为几乎没有提供任何细节。就像 VB 在项目中做什么一样,有多少线程正在工作,这里使用的自定义表单是什么..等等。

编辑:

实现启动屏幕的算法(恕我直言):)

1)创建一个自定义表单 - 启动屏幕

2)运行它在一个单独的线程上。按照您的喜好实现它的行为。

3) 在您的启动屏幕表单中,编写一个处理程序来捕获关闭启动屏幕表单的自定义卸载事件处理程序。

4) 现在,回到主线程,创建主应用程序表单。将其 Visible 属性设置为 false。

5) 编写主窗体Load 事件的偶数处理程序。在此处理程序中,触发事件以启动屏幕进行卸载。然后,使主窗体可见。

The question is not in detail.

1) What the is the relationship between the SplashScreen and the main form of the application?

2) How does SplashScreen automatically close?

I'm sure the problem here is that the main form had already started loading up in the background while SplashScreen is yet to close. Due to bad timing, the main form loads up in the background and the SplashScreen unloads... hence the flash in the taskbar.

Make them appear in serial controlled manner. There are many ways. I cannot suggest exactly how since hardly any detail has been provided. Like what is VB doing in the project, how many threads are working, what are the custom forms used here.. etc.

EDIT:

Algorithm to implement Splash screen (IMHO) :)

1) Create a custom form - splash screen

2) Run it on a separate thread. Implement it's behaviour as you like.

3) In your splash screen form, write a handler to capture a custom unload event handler which closes the splash screen form.

4) Now, back in the main thread, create you main app form. Set its Visible property to false.

5) Write even handler of the main form's Load event. In this handler, fire an event to splash screen to unload. Then, make the main form visible.

稚然 2024-10-03 05:11:23

您需要在主窗体上调用 Activate() 方法才能正确显示它。

You need to call the Activate() method on your main form in order to display it properly.

魂ガ小子 2024-10-03 05:11:23

在我在不同线程上实现的一些启动表单中,我也看到过这种情况。

通常,如果我调用 this.Activate(); 作为表单加载中的第一行代码,它往往会按预期工作。
在隐藏飞溅之后放置此通常无法正常工作。

其他有帮助的方法。

this.BringToFront();
this.TopMost = true; //setting this to true and back to false sometimes can help

In some of my implementations of splash forms on a different thread, I've seen this situation as well.

usually if I call this.Activate(); as my first line of code in the form load it tends to work as expected.
putting this after hiding the splash usually doesnt work correctly.

other methods that can help.

this.BringToFront();
this.TopMost = true; //setting this to true and back to false sometimes can help
樱桃奶球 2024-10-03 05:11:23

如果您在 Form1 Load 事件中显式设置焦点会怎样?

What if you set the focus explicitly in your Form1 Load event?

悲喜皆因你 2024-10-03 05:11:23

由于某些不明原因,焦点似乎工作正常。我将尝试将主程序的更多正常执行合并到 MyMainForm 中,并尝试找出真正导致焦点更改失败的原因。我会随时通知大家。

For some obscure reason, focus seems to be working correctly. I am going to try and incorporate more of my normal execution of my main program into the MyMainForm and try to find what really causes the focus change to fail. I will keep you all posted.

无远思近则忧 2024-10-03 05:11:23

尝试在 this.MainForm = new Form1(); 之后调用 form1.show() 它对我有用。

try calling form1.show() after this.MainForm = new Form1(); It worked for me.

浪菊怪哟 2024-10-03 05:11:23

我有同样的问题,想要简单的解决方案。

我在上面尝试过,但没有运气,但是来自上面有用信息的想法。

我尝试了我的技巧,它对我有用。

这是我的 Programs.cs 代码,工作正常:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var mainWindow = new frmMain();
        splashScreen.DisplaySplashScreen(mainWindow, 10000);
        **mainWindow.TopMost = true;**
        Application.Run(mainWindow);
    }
}

注意 mainWindow.TopMost = true;

好的,这已经足够工作了,但我不希望 mainWindow 保持在顶部。

因此,在 Shown 事件中,我添加了 this.TopMost = false;

    private void frmMain_Shown(object sender, EventArgs e)
    {
        this.TopMost = false;
    }

现在,我的应用程序正在按照我希望的方式工作。

注意:刚刚发布是为了帮助遇到与我遇到的相同问题的任何其他用户。

快乐编码:)

I had the same issue and wanted easy solution for this.

I tried above but no luck, but ideas from above useful information.

I tried my trick and it works for me.

This is my Programs.cs code which works fine:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var mainWindow = new frmMain();
        splashScreen.DisplaySplashScreen(mainWindow, 10000);
        **mainWindow.TopMost = true;**
        Application.Run(mainWindow);
    }
}

Notice the mainWindow.TopMost = true;

Ok that was working enough but I did not want the mainWindow to stay on top.

So in Shown event i added this.TopMost = false;

    private void frmMain_Shown(object sender, EventArgs e)
    {
        this.TopMost = false;
    }

Now my application is working as I wanted it to work.

Note: Just posted to help any other user who face the same issue what I faced.

Happy Coding :)

跨年 2024-10-03 05:11:23

在主窗体的加载事件中添加
this.Activate();

in you main form's load event add
this.Activate();

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