8

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.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Olyan
  • 105
  • 2
  • 6
  • This is my code. SO takes this pretty seriously, attribution is required. You have to include a link to the original code and the name of the author. – Hans Passant Oct 07 '10 at 18:10
  • I took this code a long time ago (dates months I think) and only added for the SplashScreen. Sorry if it was yours to start with. How may I add your attribution and link? – Olyan Oct 07 '10 at 20:31

8 Answers8

4

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.

Nayan
  • 3,092
  • 25
  • 34
  • Actually, the VisualBasic framework does the work automatically with regards to the SplashScreen. It displays it automatically and when the main form is displayed, it destroys the splash screen. I only have the main thread running. My loading process is done in the OnCreateMainForm where the // Do your initialization here is. – Olyan Oct 07 '10 at 17:40
  • That VB FW could be the problem. As you said, it destroys splash screen when the main form loads, then the focus might have switched to splash screen during its close action. I don't know, but you need to check VB FW u r using. Are you using it only for splash? It can be done in C# as well without VB FW. – Nayan Oct 07 '10 at 17:43
  • I started using it for the SingleInstance application. It's a charm for that. It passes my command-line arguments to the opened app and everything. I only added the splashscreen a few days ago since my initialization can have some messages to display to the user through MessageBox, so I needed a GUI element to be present. – Olyan Oct 07 '10 at 17:49
  • Well, you gain some, you lose some. I would not recommend on using third party closed source libs, unless highly recommended. You can switch to more reliable lib, or write ur own code. – Nayan Oct 07 '10 at 17:51
  • Your solution seems to be a good one. For the moment, I have continued to use the VisualBasic framework, but opted for a hybrid solution of what I already had. When I process the command-line arguments, I do a minimize and then rechange de state to normalize on the form. This sequence captures the focus ok. It has wierd behaviors in some cases, but I had to work on other problems and features to implement. – Olyan Oct 12 '10 at 15:44
4

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

cre8or
  • 387
  • 3
  • 10
3

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
Jay D
  • 3,263
  • 4
  • 32
  • 48
0

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

Thilina H
  • 5,754
  • 6
  • 26
  • 56
SlickJayD
  • 1
  • 2
0

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 :)

Iqbal
  • 1,266
  • 1
  • 17
  • 21
0

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

vulkanino
  • 9,074
  • 7
  • 44
  • 71
  • I had tried putting the this.Focus() inside the shown event, it didn't fix the problem. But now I am confused. Sometimes the focus works fine, sometimes it doesn't. – Olyan Oct 07 '10 at 17:36
0

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.

Olyan
  • 105
  • 2
  • 6
  • It seems I lost a day because of VS. I simply deleted bin and obj folders, recompiled everything with my original solution everything works just fine. Sorry for all this mess. – Olyan Oct 07 '10 at 20:32
  • Well, I am back with the same question. For an unknown reason, it worked only temporarily. And I didn't change any code. What happened for it to work for that brief period of time, I have no idea. And I am really out of ideas. – Olyan Oct 07 '10 at 21:53
  • Maybe its time to look for alternatives? You would avoid wasting time on such silly sync issues by writing your code. – Nayan Oct 08 '10 at 04:49
  • Check my answer for an algo to implement splash screen – Nayan Oct 08 '10 at 05:03
0

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