Introduction
Due to the increased starting time of my application, I needed to display the loading status, i.e. splash screen. I examined splash screens in several programs and chose the one that is used by Adobe Acrobat Reader 6. Splash screens with transparent, founded "regions" have sharp borders, like holes in windows.
Certain types have a principal feature � smooth borders of the picture on the screen. But they also have some bugs:
- When another window moves above the splash screen, an image may be lost
- If the underlying picture (e.g. the color/text of the window or other controls) was changed, we can see an abnormal border (the part of the background at the time when the splash screen was displayed). This type of splash screen was created by an algorithm (IMHO): before showing off the splash screen, the program makes a screenshot of the desktop, draws a picture with alpha-channel on it, and places the result on splash screen forms
- Sometimes this appears as a hung application
For example, a splash screen of this type with an abnormal border is shown below:
Then I found an article, OSD Window With Animation Effect, in C# by Mr.Smarty and concluded that it is a great idea. I modified the source to add the capability to change the text and image when the window is already on the screen.
Thank you very much, Mr. Smarty!
Using the Code
Before being displayed, the SplashScreen
creates the application's main form, shows a window and passes it to the constructor of the main form.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
SplashScreen splash = new SplashScreen();
splash.Show();
Application.Run(new FormMain(splash));
}
We can call the SetProgress
method for an update of status progress on the splash screen in the constructor of the main form. For example:
public partial class FormMain : Form
{
public FormMain(SplashScreen splash)
{
mSplashScreen = splash;
mSplashScreen.SetProgress("Initialize Components...", 0.0);
InitializeComponent();
mSplashScreen.SetProgress("Some task 1...", 0.2);
Thread.Sleep(1000);
mSplashScreen.SetProgress("Some task 2...", 0.4);
Thread.Sleep(1000);
mSplashScreen.SetProgress("Some task 3...", 0.6);
Thread.Sleep(1000);
mSplashScreen.SetProgress("Some task 4...", 0.8);
Thread.Sleep(1000);
mSplashScreen.SetProgress("Starting...", 1.0);
}
private SplashScreen mSplashScreen;
...
In the above code snippet, Thread.Sleep
is an emulation of continuous operations.
When the main form is ready to be displayed, we have to close the splash screen:
private void FormMain_Load(object sender, EventArgs e)
{
if (mSplashScreen != null)
mSplashScreen.Hide();
}
The appearance of the splash screen realizes in the function FormWelcome.PerformPaint
.
protected override void PerformPaint(PaintEventArgs e)
{
if (base.Handle != IntPtr.Zero)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.FillRectangle(this.mBrush, this.Bound);
g.DrawString(String.Format("{0} v{1}", Application.ProductName,
Application.ProductVersion), mTextFont, mTextBrush, 40, 20);
g.DrawString(mMessageText, SystemFonts.DialogFont, mTextBrush,
40, this.Height - 40);
float w = this.Width - 10 * 2;
mCompletionFraction, this.Height - 20);
g.DrawImageUnscaledAndClipped(
Properties.Resources.image_load_progress_texture,
new Rectangle(10, 36, (int)(w * mCompletionFraction),
Properties.Resources.image_load_progress_texture.Height));
}
}
Points of Interest
- Before OSD, I tried to create the splash screen as a Form in a separate thread, but this method didn't solve the problem with abnormal borders when the background changes. However, if we have a rectangle image, this method can be useful.
- I found that drawing the alpha-channel images with tiles over the other images with gradient gives an interesting effect and applied it for drawing the progress bar.
- I also tried another method unlike that of the splash screen: we can create only the main Form of an application with the progress bar, and create (asynchronously) another interface on a dedicated
UserControl
after showing the main Form on the screen.
History
- 31/8/2007 - v1.0 First release