Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / Windows Forms
Article

Splash Screen with Semitransparent Borders

Rate me:
Please Sign up or sign in to vote.
3.65/5 (20 votes)
17 Nov 20072 min read 70.3K   3.5K   72   18
This article shows how to create a Splash Screen with alpha-channel image and semitransparent borders.
Screenshot - Article.png

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:

Example of abnormal border of splash screen

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.

C#
[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:

C#
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:

C#
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.

C#
protected override void PerformPaint(PaintEventArgs e)
{
    if (base.Handle != IntPtr.Zero)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.HighQuality;

        //background (png with alpha-channel)
        g.FillRectangle(this.mBrush, this.Bound);

        //text
        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);

        //progress bar
        float w = this.Width - 10 * 2;
        //g.DrawLine(mPenProgress, 40, this.Height - 20, 40 + w *
            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

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Question64-bit platform framework 4 Pin
Byron - Ecuador29-Aug-13 5:37
professionalByron - Ecuador29-Aug-13 5:37 
AnswerRe: 64-bit platform framework 4 Pin
Vladimir N.29-Aug-13 5:43
Vladimir N.29-Aug-13 5:43 
GeneralBeautiful solution. Pin
Diamonddrake9-Mar-10 16:34
Diamonddrake9-Mar-10 16:34 
GeneralSingleton pattern on main form Pin
wond3rboy28-Sep-08 5:37
wond3rboy28-Sep-08 5:37 
AnswerRe: Singleton pattern on main form Pin
Vladimir N.28-Sep-08 17:33
Vladimir N.28-Sep-08 17:33 
* Code *

* Startup:

SplashScreen splash = new SplashScreen();
splash.Show();
FormMain.Splash = splash;
Application.Run(FormMain.Instance);

* Form

namespace MyNameSpace
{
    public partial class FormMain : Form
    {
        private static SplashScreen mSplash; 
        private static FormMain mInstance;

        // make the default constructor private, so that no can directly create it.
        private FormMain(SplashScreen splash)
        {
            InitializeComponent();
            if(splash != null)
                splash...
            ...
        }

        // PROPERTY that can only get the single instance of this class.
        public static FormMain Instance
        {
            get
            {
                if(mInstance == null)
                    mInstance = new FormMain(mSplash);
                return mInstance;
            }
        }
        public static SplashScreen
        {
            get{ return mSplash; }
            set{ mSplash = value; }
        }
    }
}

QuestionVB.Net? Pin
OnAir14-Feb-08 9:17
OnAir14-Feb-08 9:17 
AnswerRe: VB.Net? Pin
Vladimir N.14-Feb-08 16:44
Vladimir N.14-Feb-08 16:44 
GeneralTopMost Pin
RogerRabbit7824-Jan-08 20:44
RogerRabbit7824-Jan-08 20:44 
AnswerRe: TopMost Pin
Vladimir N.24-Jan-08 20:53
Vladimir N.24-Jan-08 20:53 
GeneralGood Splash Pin
Pedro Henrique Liberato12-Dec-07 16:23
Pedro Henrique Liberato12-Dec-07 16:23 
GeneralRe: THE BEST SPLASH OF THE WORLD Pin
Muhammed Zakeer27-Jun-11 7:13
Muhammed Zakeer27-Jun-11 7:13 
GeneralGreat code! Pin
Mojster_no124-Nov-07 11:24
Mojster_no124-Nov-07 11:24 
Generaltoo bad code Pin
Sergey Morenko8-Nov-07 7:35
professionalSergey Morenko8-Nov-07 7:35 
Answercode fixed and updated Pin
Vladimir N.8-Nov-07 8:00
Vladimir N.8-Nov-07 8:00 
JokeRe: too bad code Pin
dethtroll9-Nov-07 1:18
dethtroll9-Nov-07 1:18 
GeneralRe: too bad code [modified] Pin
Vladimir N.9-Nov-07 1:30
Vladimir N.9-Nov-07 1:30 
JokeRe: too bad code Pin
dethtroll12-Nov-07 2:46
dethtroll12-Nov-07 2:46 
GeneralRe: too bad code Pin
fadee12-Nov-07 20:37
fadee12-Nov-07 20:37 

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

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