Click here to Skip to main content
Licence CPOL
First Posted 12 Jul 2006
Views 59,370
Downloads 965
Bookmarked 110 times

Use a splash screen in your application

By | 12 Jul 2006 | Article
This article will show you how to display a splash screen during application initialization using C# in VS2005

Sample Image - usesplashscreen.jpg

Introduction

This article will show you how to display a splash screen during application initialization using C# in VS2005 IDE.

Background

Sometimes, we have to put a lot of initialization code into the MainForm's OnLoad() override. Due to this, when the application starts up, it looks like a mess: The main application form just doesn't pop up nicely and ready to be used. Now we need to create a splash screen, let's begin.

Preparations

  1. Create a Windows Forms project Named SplashScreen
  2. Delete Form1.cs
  3. Add a new Form named frmMain

1. Creating the Core Code

Firstly, create an interface called ISplashForm, which includes a method named SetStatusInfo in order to display the loading status on the splash screen. Once done, the interface should look like this:

public interface ISplashForm
{
    void SetStatusInfo(string NewStatusInfo);
}

Secondly, create a class called Splasher, where static members Show, Close and the Status writeonly property can be used as their names suggest to show and close the Splash Screen as well as to update the loading status displayed on the SplashForm. Here is what the implementation of the class looks like:

using System;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;

    public class Splasher
    {
        private static Form m_SplashForm = null;
        private static ISplashForm m_SplashInterface = null;
        private static Thread m_SplashThread = null;
        private static string m_TempStatus = string.Empty;

        /// <summary>
        /// Show the SplashForm
        /// </summary>
        public static void Show(Type splashFormType)
        {
            if (m_SplashThread != null)
                return;
            if (splashFormType == null)
            {
                throw (new Exception("splashFormType is null"));
            }

            m_SplashThread = new Thread(new ThreadStart(delegate()
            {
                CreateInstance(splashFormType);
                Application.Run(m_SplashForm);
            }));

            m_SplashThread.IsBackground = true;
            m_SplashThread.SetApartmentState(ApartmentState.STA);
            m_SplashThread.Start();
        }

        /// <summary>
        /// set the loading Status
        /// </summary>
        public static string Status
        {
            set
            {
                if (m_SplashInterface == null || m_SplashForm == null)
                {
                    m_TempStatus = value;
                    return;
                }
                m_SplashForm.Invoke(
                        new SplashStatusChangedHandle(delegate(string str)
                { m_SplashInterface.SetStatusInfo(str); }),
                        new object[] { value }
                    );
            }

        }

        /// <summary>
        /// Close the SplashForm
        /// </summary>
        public static void Close()
        {
            if (m_SplashThread == null || m_SplashForm == null) return;

            try
            {
                m_SplashForm.Invoke(new MethodInvoker(m_SplashForm.Close));
            }
            catch (Exception)
            {
            }
            m_SplashThread = null;
            m_SplashForm = null;
        }

        private static void CreateInstance(Type FormType)
        {

            object obj = FormType.InvokeMember(null,
                                BindingFlags.DeclaredOnly |
                                BindingFlags.Public |
                BindingFlags.NonPublic |
                                BindingFlags.Instance |
                BindingFlags.CreateInstance, null, null, null);
            m_SplashForm = obj as Form;
            m_SplashInterface = obj as ISplashForm;
            if (m_SplashForm == null)
            {
                throw (new Exception("Splash Screen must inherit from
                        System.Windows.Forms.Form"));
            }
            if (m_SplashInterface == null)
            {
                throw (new Exception("must implement interface ISplashForm"));
            }

            if (!string.IsNullOrEmpty(m_TempStatus))
                m_SplashInterface.SetStatusInfo(m_TempStatus);
        }

        private delegate void SplashStatusChangedHandle(string NewStatusInfo);
    }

2. Creating the Splash Screen

Just create a new Windows Form named frmSplash. The form should be centered on the screen (StartPosition), be topmost (TopMost) and shouldn't have a border (FormBorderStyle), set the BackgroundImage property to your splash image and set the form size equal to the image size. In order to display the loading status on the form, we need to place a label on the form and then implement ISplashForm. If the label is called lbStatusInfo, the ISplashForm implementation should look like this:

void ISplashForm.SetStatusInfo(string NewStatusInfo)
{
   lbStatusInfo.Text = NewStatusInfo;
}

3. Modifying the MainForm's code

Now we need to make some modifications to the frmMain class. Once done, the constructed function should look somewhat like this:

public frmMain()
{

    Splasher.Status = "Creating MainForm...";
    System.Threading.Thread.Sleep(1000);

    InitializeComponent();

    Splasher.Status = "Loading Files...";
    System.Threading.Thread.Sleep(1500);

    Splasher.Status = "Loading Plug/Ins...";
    System.Threading.Thread.Sleep(1500);

     Splasher.Status = "Sleeping 1 second...";
     System.Threading.Thread.Sleep(1000);

     Splasher.Close();
}

4. Modifying the Entry Point function

In order to use Splash Screen, we have to modify our entry point function appropriately:

[STAThread]
static void Main()
{
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Splasher.Show(typeof(frmSplash));
      frmMain MyMainForm = new frmMain();
      Application.Run(MyMainForm);
}

That's all about it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

cncxz



China China

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralAppreciate your work!! PinmemberLi Shu1:07 23 Jan '10  
GeneralQuite useful PinmemberMember 26446008:12 7 Mar '09  
GeneralBug PinmemberSimon Stevens23:19 18 Jun '08  
Hi,
 
3 problems:
 
1) If you run this as a compiled app, by double clicking the .exe in explorer, when the splash screen closes, the main form appears behind the explorer window. I've played around with it a bit, and can't fix this. I even tried adding a delay in the splash screen close so that the main form was displayed before the splash screen closed. When I did this, the main form displayed correctly (behind the splash screen but in front of the explorer window) but as soon as the splash screen was closed and the message pump ended the explorer window took focus.
 
2) If you attempt to set the status on the splash screen form before the thread has finished loading the splash screen you get an exception. This doesn't happen very often. It's a race condition between the main thread and the thread that's creating the splash form. You can make it more likely to happen by putting a Thread.Sleep(1000) in the splash screen creation thread.
 
3) You are swallowing all exceptions in the close method. This is very bad practise. What exceptions are you expecting here?
 
Simon

Generalproblem with ApartmentState.STA PinmemberOssan Dust23:24 20 May '08  
Newsuse Opacity attribute when m_SplashForm is closing Pinmemberwangkuang54:53 5 Mar '08  
GeneralExcellent work! PinmemberAlan Yost10:25 30 Nov '07  
GeneralBug [modified] Pinmembertranbagu21:21 25 Oct '07  
GeneralRe: Bug -> solution Pinmemberchr.dev2:25 16 Nov '07  
GeneralRe: Bug -> solution Pinmemberwangkuang53:45 7 Mar '08  
Generalnice! Pinmemberradioman@gawab.com21:49 6 Aug '07  
GeneralREALLY GREAT ! Pinmemberlucatoldo1:27 18 Jun '07  
GeneralAdd new operation during the splash Pinmemberayeleteric19:44 10 Jun '07  
GeneralGreat example! PinmemberDVroegop3:53 13 Apr '07  
GeneralThanks PinmemberMember #383675911:03 20 Mar '07  
GeneralAdding more "static" labels. PinmemberCMercs5:55 14 Feb '07  
Generalvb.net version PinmemberGreg Hazzard10:17 7 Nov '06  
GeneralRe: vb.net version PinmemberGreg Hazzard10:37 9 Nov '06  
GeneralRe: vb.net version Pinmembercncxz21:35 4 Feb '07  
QuestionTopMost property Pinmembermarutj16:09 2 Oct '06  
GeneralfrmMain does not appear in the Foreground PinmemberZupcoder13:17 9 Sep '06  
GeneralRe: frmMain does not appear in the Foreground PinmemberAllad20:33 11 Jan '07  
Questionthe splash won't disappear PinmemberUnruled Boy21:38 13 Aug '06  
QuestionVB version of this code? PinmemberJoshua Ng22:30 18 Jul '06  
AnswerRe: VB version of this code? [modified] Pinmembercncxz23:53 18 Jul '06  
GeneralRe: VB version of this code? PinmemberJoshua Ng20:22 19 Jul '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120529.1 | Last Updated 12 Jul 2006
Article Copyright 2006 by cncxz
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid