Proper splash screen design

Hello everybody,
I want to ask what is the best practice for splash screen design. Should the main method start two separate threads for the main form and splash form? Or some other approach? Like the main form spawning the splash thread? Because I'm rather confused, I've been reading quite a few articles on splash screens all use different approaches and entry points. So I just wanted to ask what's the best practice about the problem. Any advice is greatly appreciated.
Regards
[526 byte] By [gamehack] at [2007-12-16]
# 1
Although you could use two threads, one for the splash screen and one for main form, it is not required. I spawn and show the splash screen before even creating the main form and then when the main form is created, set the splash screen's owner to it.

I have written a simple example on how to do this on the following blog entry:

http://davidkean.net/archive/2005/02/05/291.aspx

DavidM.Kean at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 2
Thank you very much. But I'll still try to make a threaded splash screen and I will see whether I can do it. Thanks a lot.
gamehack at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 3
gamehack - If your using .net 2.0 and still having problems with it you could try something like I do for my splash screens, now that cross thread execution is more restricted (well it throws exceptions easier now basically)...

see my post below had some corrections to this one and just made a new reply...

Later...

Andy J

AJNothing82 at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 4
sorry correction to my code I just posted... I misused the BackgroundWorker... here's one that won't crash if you have COM objects like the WebBrowser Control on the main form... sorry for the confusion... heh still getting used to the new objects in 2.0.

I added a new class to load the Form 1 in it's own STAThread application... and removed the BackgroundWorker stuff...



- begin Program.cs --

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.ComponentModel;
using System.Threading;

namespace SplashTemplate
{
static class
Program
{
internal static Thread _mainThread;
internal static SplashForm _splash;

internal static bool _startMainFormLoad = false;

/// <summary>
///
The main entry point for the application.
///
</summary>

[STAThread]
static void Main()
{
_mainThread = new Thread(new ThreadStart(RunMain));
_mainThread.SetApartmentState(ApartmentState.STA);
_mainThread.Priority = ThreadPriority.Normal;
_mainThread.IsBackground = false;
_mainThread.Start();

_splash = new SplashForm();
Application.Run(_splash);
}

static void RunMain()
{
MainEntryPoint.ShowMain();
}

static internal void UpdateSplasherStatus(string text)
{
_splash.SetStatusText(text);
}
}

}
- end Program.cs --
- being MainEntryPoint.cs -

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace SplashTemplate
{
static class MainEntryPoint
{
internal static Form1 _main;

[STAThread]
internal static void ShowMain()
{
_main =
new Form1();
Application.Run(_main);
}
}
}

- end MainEntryPoint.cs --

- begin Form1.cs --

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace SplashTemplate
{
public partial class Form1 : Form
{
public Form1()
{
while (!Program._startMainFormBuild)
{
//here to make sure the splash screen is displayed before it starts
//going to look into working around an innerexception when I do this
//with events instead...
}

Program.UpdateSplasherStatus("Initializing...");
InitializeComponent();
Thread.Sleep(2000);

Program.UpdateSplasherStatus("Working...");
//simulate work
Thread.Sleep(2000);
}

private void Form1_Shown(object sender, EventArgs e)
{
Program._splash.fakeClose();
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
Program._splash.tryClose();
}
}
}

-- end Form1.cs --

-- begin SplashForm.cs --

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace SplashTemplate
{
public partial class SplashForm : Form
{
internal delegate void closeDelegate();
internal delegate void statusDelegate(string text);

public SplashForm()
{
InitializeComponent();
}

internal void fakeClose()
{
if (this.InvokeRequired)
{
closeDelegate cD = new closeDelegate(fakeClose);
this.Invoke(cD);
}
else
{
this.Visible = false;
}
}

//you may have to add other functions like this to clean up other
//GUI objects that won't dispose in a thread safe manner on the splash screen
//for me it's some Infragistics Controls...
internal void tryClose()
{
if (this.InvokeRequired)
{
closeDelegate cD = new closeDelegate(tryClose);
this.Invoke(cD);
}
else
{
this.Close();
}
}

internal void SetStatusText(string stat)
{
if (this.InvokeRequired)
{
statusDelegate sD = new statusDelegate(SetStatusText);
this.Invoke(sD, new object[]{ stat });
}
else
{
_statusTB.Text = stat;
}
}

private void SplashForm_Load(object sender, EventArgs e)
{
Program._startMainFormBuild = true;
}
}
}

-- end SplashForm.cs --


Sorry again for the confusion if anyone even read that entry before I posted this one, had a few corrections from pulling the code snips out of my project Big Smile

Later...

Andy J

AJNothing82 at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 5

How do you deal with the delay while the .NET framework is loaded from disk?

I've found that it can take up to 20 sec for the .NET framework to load after a reboot, meaning that it takes 20 second from the time the user clicks my app icon until the first line of my .NET code is called - which shows the splashscreen.

Is there any way to get a splashscreen displayed before the .NET framework is loaded?

Thanks

ADNG

DotNetGuy at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 6

I think I've found the solution to the .NET startup delay problem.

There is a Win32 component that loads up your splash screen JPG instantly, and then loads your .NET application (and the framework) on a background thread.

Its pretty cool, cause it makes you application appear to start instanty.

Its at http://www.quicksplash.net

DotNetGuy at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...