A snapshot of the Shutter style splash
Splash is useful in many applications, especially in some slow-loading processes. There is a splash screen in Visual C++ ATL, but it has many useless functions and is somehow rigid. So, you can create a flexible splash.
To create the multithread splash, you can refer to the article “A Splash Screen with Alpha Blending,” written by Leonardo Bernardini. In it, maybe there is something different from my splash class, but they are both based on the same technique.
How It Works
If you are not interested in it, you can skip this section and go to the next section, where you can learn how to use it.
As you can see, the splash screen is in fact a window without a title bar and board. So, you create a window to draw what you want.
You derive CUltraSplashWnd from the CWnd class and add a member function to create a real window: The first part creates an invisible window used as the parent so that the splash window won’t show in the task bar. Here is the code:
BOOL CUltraSplashWnd::Create() { //Create an invisible parent window LPCTSTR pszWndClass = AfxRegisterWndClass(0); m_wndOwner.CreateEx(0, AfxRegisterWndClass(0), _T(""), WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 0); //Create splash window CreateEx(0, AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW)), "UltraSplashWnd", WS_POPUP | WS_VISIBLE, 0, 0, m_bm.bmWidth, //Width of bitmap m_bm.bmHeight, //Height of bitmap m_wndOwner.GetSafeHwnd(), NULL, NULL); ShowCursor(FALSE); //Hide the cursor m_bClose = false; Show(); return TRUE; }
You use Show() to begin drawing.
void CUltraSplashWnd::Show() { while (!m_bClose) { RedrawWindow(); } }
As you can see, this loop forces a redraw of the window, so that the animation can display. The animation implements in OnPaint(). You must create a memory DC to store the splash bitmap. After that, you check the animation style and jump to the corresponding drawing function.
void CUltraSplashWnd::OnPaint() { CPaintDC dc(this); // device context for painting m_pDC = &dc; //TODO: Add your message handler code here if(!m_MemDC.GetSafeHdc()) { m_MemDC.CreateCompatibleDC(&dc); //Create the memory DC to //store the bitmap m_MemDC.SelectObject(&m_bitmap); //Select the bitmap to //the DC } bool bOver = false; switch (m_nStyle) { case USS_LEFT2RIGHT: //left to right bOver = Left2Right(m_CtrlVal1); break; case USS_RIGHT2LEFT: //right to left bOver = Right2Left(m_CtrlVal1); break; case USS_UP2DOWN: //up to down bOver = Up2Down(m_CtrlVal1); break; case USS_DOWN2UP: //down to up bOver = Down2Up(m_CtrlVal1); break; case USS_HORISHUTTER: //horizontal shutter bOver = HoriShutter(m_CtrlVal1,m_CtrlVal2); break; case USS_VERTSHUTTER: //vertical shutter bOver = VertShutter(m_CtrlVal1,m_CtrlVal2); break; case USS_RANDOMBOX: //random box bOver = RandomBox(m_CtrlVal3); break; default: //Static drawing, copy picture to dc directly m_pDC->BitBlt(0, 0, m_bm.bmWidth, m_bm.bmHeight, &m_MemDC, 0, 0, SRCCOPY); break; } //set style to static after animated if (bOver) m_nStyle = USS_STATIC; // Do not call CWnd::OnPaint() for painting messages }
For example: If you render the splash bitmap left to right, you use the function as follows: