Splash screen does not return focus to main form

2019-04-24 10:00发布

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.

7条回答
ら.Afraid
2楼-- · 2019-04-24 10:33

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
查看更多
登录 后发表回答