Animated Multithread Splash

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:

More by Author

Must Read