Adding a Non-Modal Splash Screen to your .NET Compact Framework Application

A few weeks ago, Anthony Wong posted an excellent entry on adding a modal splash screen to your .NET Compact Framework application.  His post started me wondering about how to create a non-modal splash screen.  Why a non-modal splash screen?  By making the splash screen non-modal, the application's main form can perform initialization work while the splash form is displayed.  Once initialization is complete, the main form will close the splash screen form.

The snippets below display the relevant code for a single-threaded application that displays a non-modal splash screen, performs initialization and closes the splash screen when finished.  Please note that this example uses version 2 of the .NET Compact Framework.

Main application form
//---------------------------------------------------------------------//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY //KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE //IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A //PARTICULAR PURPOSE.//---------------------------------------------------------------------namespace NonModalSplashSnippet{    public partial class MainForm() : Form    {        private SplashForm m_Splash;        public MainForm()        {            // create and display the splash screen form            //  and make the main form it's owner            this.m_Splash = new SplashForm();            this.m_Splash.Owner = this;            this.m_Splash.Show();            // process the message queue            //  this is done to allow the splash            //  screen to be painted            Application.DoEvents();            // disable the main form            //  to avoid the title bar            //  being drawn over the splash screen            //  during initialization            this.Enabled = false;            InitializeComponent();        }        private void MainForm_Load(object sender, EventArgs e)        {            // do form load-time work            //  this sleep simulates the work            System.Threading.Thread.Sleep(10000);            // re-enable the form and            //  tell Windows Forms to             //  make our form visible            //  right now            this.Enabled = true;            this.Visible = true;            // close the splash screen            this.m_Splash.Close();         }    }}
Splash screen form

//---------------------------------------------------------------------//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY //KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE //IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A //PARTICULAR PURPOSE.//---------------------------------------------------------------------namespace NonModalSplashSnippet{    public partial class SplashForm() : Form    {        public SplashForm()        {            // use the form designer to set            //  ControlBox == false            //  WindowState == Maximized            // This results in a full screen splash            //  form without a title bar            InitializeComponent();        }        protected override OnPaint(PaintEventArgs e)        {            // display a message            StringFormat sf = new StringFormat();            sf.Alignment = StringAlignment.Center;            sf.LineAlignment = StringAlignment.Center;             e.Graphics.DrawString(".NET Compact Framework",                                   this.Font,                                   new SolidBrush(Color.Blue),                                   Screen.PrimaryScreen.Bounds,                                   sf);        }    }}

How it works
Let's walk through the snippets and discuss what is happening.

The first job our application's main form performs is the creation of the splash screen form.  Once created, the splash screen's owner is set to the instance of the MainForm class and then it is shown.
    this.m_Splash = new SplashForm();    this.m_Splash.Owner = this;    this.m_Splash.Show();The setting of the splash form's owner is an important step that instructs the operating system, provided your application is the currently active application, to display the application's main form once the splash form is closed.

To ensure that the splash screen form gets painted (and all other pending messages get processed) the static Application.DoEvents method is called.
    Application.DoEvents();

To avoid the main form's caption being displayed on top of the splash screen, the MainForm constructor sets the form's enabled property to false and then calls InitializeComponent (created by the Visual Studio 2005 form designer).
    this.Enabled = false;Since the default value for the Enabled property is true, the designer does not explicitly set the value, which leaves our setting of false preserved.

The MainForm_Load method is where initialization will occur.  In my snippet, I sleep for a few seconds to simulate work being performed.  Once the initialization is complete, the main form is re-enabled and marked visible.
    this.Enabled = true;    this.Visible = true;By explicitly marking the main form visible, the system is being told that it is now time to display the form.

The last thing done in MainForm_Load is to close the splash screen.
    this.m_Splash.Close();
Once the splash screen is closed, the main form is displayed and is ready to be used.

Enjoy!
-- DK

[Edit: update links]
[Edit: fix error]

Disclaimer(s):
This posting is provided "AS IS" with no warranties, and confers no rights.
Some of the information contained within this post may be in relation to beta software. Any and all details are subject to change.