Introduction
Using MFC-based classes -- even with your own threads -- may lead to hang-up of the splash screen repainting while loading the application. This is because MFC has synchronization on the message queue level. So, the application stops responding to the user. CSplashWnd
is a class that makes it easy to use splash screens that can always paint themselves. It is implemented using the Win32 API, but you can use it in MFC applications, as well.
How to Use the Class
The CSplashWnd
uses GDI+ to show images. It allows you to use a variety of image types including BMP, GIF, JPEG, PNG, TIFF and EMF. However, you have to initialize the GDI+ library:
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
...
GdiplusShutdown(gdiplusToken);
The use of CSplashWnd
is very simple. Just add SplashWnd.cpp and SplashWnd.h into your project and then include SplashWnd.h in your program. To initialize the splash screen, use CSplashWnd::SetImage
. This method sets the image you want to see while loading the application. It can look like this:
...
CSplashWnd splash;
splash.SetImage(pImage);
splash.Show();
splash.Hide();
...
The splash screen can have a button on the taskbar. It is created only if CSplashWnd::SetWindowName
is invoked before CSplashWnd::Show
. A button on the taskbar may be useful if the splash screen appears before any window is created. In that case, the user can easily find the application. You can indicate the loading progress using the CSplashWnd::SetProgress
method. The first call of CSplashWnd::SetProgress
leads to creating a progress control at the bottom of the splash window. It also sets the progress control to the initial state. All subsequent calls just update the progress state.
You could show more details of loading or computing process by passing text description of progress stage to CSplashWnd::SetProgress
method using text string or string resource ID as additional input parameter.
...
splash.Show()
splash.SetProgress(0, L"Loading...");
for (int i =0; i < 100; ++i)
{
splash.SetProgress(i);
}
splash.SetProgress(100, L"Done.");
...
If the length of the loading operation is known, you'll want to use the CSplashWnd::SetAutoProgress
method. It automatically updates the progress state using its own timer. At the moment, it updates the state one step per second. The previous code will now look like:
...
splash.Show()
splash.SetAutoProgress(0, 100, 100);
for (int i =0; i < 100; ++i)
{
}
...
History
- August 9, 2006 - The class was written.
- May 25, 2007 - Some synchronization has been added and the timer message ID has been fixed.
- June 20, 2008 - New features: multimonitor support, text progress status, support for external resource handles.