Multi-threaded Splash Screen in WinForms-VBForums
Results 1 to 2 of 2

Thread: Multi-threaded Splash Screen in WinForms

  1. #1

    Thread Starter
    .NUT jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    87,325

    Multi-threaded Splash Screen in WinForms

    Since VB 2005, VB.NET has provided something called the Application Framework, which lets you configure certain application characteristics with a few clicks. One of those characteristics is the splash screen for the application. Displaying a splash screen is not as straightforward as it may first appear. The VB Application Framework creates the splash screen on a secondary thread, so that it doesn't interfere with the main form. It will also keep the splash screen open for a minimum amount of time, even if the main form takes less time to be ready to display. If the main form is not ready within that time, the splash screen will remain open until it is.

    The code below provides that same behaviour in a C# application. Add a form to your application to use as a splash screen and add the following code:
    csharp Code:
    1. using System;
    2. using System.Threading;
    3. using System.Windows.Forms;
    4. using Timer = System.Timers.Timer;
    5.  
    6. namespace Multi_threaded_Splash_Screen
    7. {
    8.     public partial class SplashScreen : Form
    9.     {
    10.         /// <summary>
    11.         /// Contains information for creating a splash screen.
    12.         /// </summary>
    13.         private struct SplashScreenInfo
    14.         {
    15.             /// <summary>
    16.             /// The main form for the application.
    17.             /// </summary>
    18.             public Form StartupForm;
    19.             /// <summary>
    20.             /// The minimum number of milliseconds for which to display the splash screen.
    21.             /// </summary>
    22.             public int MinimumDisplayTime;
    23.             /// <summary>
    24.             /// Signals the main thread when a handler has been added to the main form's Load event.
    25.             /// </summary>
    26.             public ManualResetEvent Handle;
    27.         }
    28.  
    29.         /// <summary>
    30.         /// Tells the splash screen when it has been open for the minimum amount of time.
    31.         /// </summary>
    32.         private Timer timer = new Timer();
    33.         /// <summary>
    34.         /// The minimum number of milliseconds for which to display the splash screen.
    35.         /// </summary>
    36.         private bool minimumDisplayTimeExpired = false;
    37.         /// <summary>
    38.         /// Used to synchronise multiple threads.
    39.         /// </summary>
    40.         private object syncRoot = new object();
    41.         /// <summary>
    42.         /// Signals the main thread when the splash screen is ready to close.
    43.         /// </summary>
    44.         private ManualResetEvent closeHandle;
    45.  
    46.         /// <summary>
    47.         /// Creates a new instance of the SplashScreen class.
    48.         /// </summary>
    49.         /// <param name="startupForm">
    50.         /// The main form for the application.
    51.         /// </param>
    52.         /// <param name="minimumDisplayTime">
    53.         /// The minimum number of milliseconds for which to display the splash screen.
    54.         /// </param>
    55.         private SplashScreen(Form startupForm, int minimumDisplayTime)
    56.         {
    57.             InitializeComponent();
    58.  
    59.             // We need to know when the main form is ready to be displayed.
    60.             startupForm.Load += startupForm_Load;
    61.  
    62.             // We need to know when the splash screen is ready to be dismissed.
    63.             timer.Elapsed += timer_Elapsed;
    64.             timer.Interval = minimumDisplayTime;
    65.             timer.Start();
    66.         }
    67.  
    68.         /// <summary>
    69.         /// Displays a splash screen.
    70.         /// </summary>
    71.         /// <param name="startupForm">
    72.         /// The main form for the application.
    73.         /// </param>
    74.         /// <param name="minimumDisplayTime">
    75.         /// The minimum number of milliseconds for which to display the splash screen.
    76.         /// </param>
    77.         public static void DisplaySplashScreen(Form startupForm, int minimumDisplayTime)
    78.         {
    79.             var continueHandle = new ManualResetEvent(false);
    80.  
    81.             // Create and display the splash screen on a secondary thread.
    82.             new Thread(DisplaySplashScreen).Start(new SplashScreenInfo
    83.                                                       {
    84.                                                           StartupForm = startupForm,
    85.                                                           MinimumDisplayTime = minimumDisplayTime,
    86.                                                           Handle = continueHandle
    87.                                                       });
    88.  
    89.             // The handler must be added to the main form's Load event before the main thread can safely continue.
    90.             continueHandle.WaitOne();
    91.         }
    92.  
    93.         /// <summary>
    94.         /// Displays a splash screen.
    95.         /// </summary>
    96.         /// <param name="info">
    97.         /// Contains information for creating a splash screen.
    98.         /// </param>
    99.         private static void DisplaySplashScreen(object info)
    100.         {
    101.             var ssi = (SplashScreenInfo) info;
    102.             var splashScreen = new SplashScreen(ssi.StartupForm, ssi.MinimumDisplayTime);
    103.  
    104.             // The main form's Load event has been handled so the main thread can safely continue.
    105.             ssi.Handle.Set();
    106.  
    107.             // Display the splash screen.
    108.             Application.Run(splashScreen);
    109.         }
    110.  
    111.         private void startupForm_Load(object sender, EventArgs e)
    112.         {
    113.             lock (syncRoot)
    114.             {
    115.                 if (!minimumDisplayTimeExpired)
    116.                 {
    117.                     // The splash screen is not ready to be dismissed so we must make the main form wait.
    118.                     closeHandle = new ManualResetEvent(false);
    119.                 }
    120.             }
    121.  
    122.             if (closeHandle != null)
    123.             {
    124.                 // The splash screen is not ready to be dismissed so we must make the main form wait.
    125.                 closeHandle.WaitOne();
    126.             }
    127.  
    128.             // Close the splash screen and allow the main form to be displayed.
    129.             this.Invoke(new MethodInvoker(this.Close));
    130.         }
    131.  
    132.         private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    133.         {
    134.             lock (syncRoot)
    135.             {
    136.                 if (closeHandle == null)
    137.                 {
    138.                     // The splash screen is ready to be dismissed before the main form is ready to be displayed.
    139.                     // Allow the main form to be displayed as soon as it is ready.
    140.                     minimumDisplayTimeExpired = true;
    141.                 }
    142.                 else
    143.                 {
    144.                     // The main form is already ready to be displayed and is waiting for the splash screen.
    145.                     closeHandle.Set();
    146.                 }
    147.             }
    148.         }
    149.     }
    150. }
    You may need to change the namespace and, if you didn't name the form "SplashScreen", the class name. Now go to the Program.cs code file and change your Main method to look something like this:
    csharp Code:
    1. /// <summary>
    2. /// The main entry point for the application.
    3. /// </summary>
    4. [STAThread]
    5. static void Main()
    6. {
    7.     Application.EnableVisualStyles();
    8.     Application.SetCompatibleTextRenderingDefault(false);
    9.  
    10.     var mainWindow = new MainWindow();
    11.  
    12.     SplashScreen.DisplaySplashScreen(mainWindow, 3000);
    13.  
    14.     Application.Run(mainWindow);
    15. }
    Again, change the class name(s) if they don't match your own. Now run the project and you'll see your splash screen displayed for at least 3 seconds and then it will disappear and your startup form will be displayed. If the startup form takes longer than that minimum of 3 seconds to be ready to display then the splash screen will stay open as long as it takes. You can test this by adding a Load event handler to the startup form and calling Thread.Sleep with a value greater than 3000, e.g. 10,000. You can change the minimum time by passing a different value to the second parameter of DisplaySplashScreen.

    2007-2014

    Why is my data not saved to my database? | MSDN Data Walkthroughs
    MSDN "How Do I?" Videos: VB | C#
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts) | WP8 Turnstile Feather Transition with Pivot Control
    Beginner Tutorials: VB | C# | SQL

  2. #2
    Hyperactive Member imadthemad's Avatar
    Join Date
    May 2005
    Posts
    337

    Re: Multi-threaded Splash Screen in WinForms

    this is pretty neat.
    I don't code in C# so any pro programmer care to volunteer and convert this code into vb?
    could be useful to reload the splash screen if u need the application to reload resources without closing it and opening it again...
    Basketball-NBA Dream status - quit
    Programming-Next Bill Gates Dream status - quit
    Becoming a doctor dream - LIVING IT: Med 2\4

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.