www.gusucode.com > 一个VC++ GUI测试程序-源码程序 > 一个VC++ GUI测试程序-源码程序/code/Splash.cpp

    //Download by http://www.NewXing.com
/////////////////////////////////////////////////////////////////////////
// 类名:CSplashWnd
// 功能:动态菲屏显示效果,具有下面属性:
//		(-1	-- 随机显示,		0	-- 水平交错效果,		1	-- 垂直交错效果,
//		 2	-- 水平百叶窗效果,	3	-- 垂直百叶窗效果,		4	-- 随机积木效果,
//		 5	-- 滤镜效果,		6	-- 垂直平分扫描,		7	-- 水平平分扫描,
//		 8	-- 水平交叉移动,	9	-- 垂直交叉移动,		10	-- 垂直栅条效果,
//		 11	-- 水平栅条效果,	12	-- 环形扫锚效果,		13	-- 缩放效果,
//		 14	-- 矩形扩张效果,	15	-- 椭圆扩张效果,		16	-- 圆角矩形扩张,
//		 17	-- 渐显效果,		18	-- 渐隐效果,			19	-- 正常显示)	
// 修改:徐景周(jingzhou_xu@163.net)
// 组织:未来工作室(Future Studio)
// 日期:2002.1.8
////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"
#include "Splash.h"

//////////////////// Defines ////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define MOUSE_MOVE 0xF012

BEGIN_MESSAGE_MAP(CSplashThread, CWinThread)
	//{{AFX_MSG_MAP(CSplashThread)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

IMPLEMENT_DYNCREATE(CSplashThread, CWinThread)

CSplashThread::CSplashThread()
{
}

CSplashThread::~CSplashThread()
{
}

BOOL CSplashThread::InitInstance()
{
  //Attach this threads UI state to the main one, This will ensure that 
  //the activation state is managed consistenly across the two threads
  ASSERT(AfxGetApp());
  BOOL bSuccess = AttachThreadInput(m_nThreadID, AfxGetApp()->m_nThreadID, TRUE);
  if (!bSuccess)
    TRACE(_T("Failed in call to AttachThredInput, GetLastError:%d\n"), ::GetLastError());

  // 此处创建菲屏窗口
  BOOL bCreated = m_SplashScreen.Create();
	VERIFY(bCreated);

  m_pMainWnd = &m_SplashScreen;
	return bCreated;
}

void CSplashThread::HideSplash()
{
  //Wait until the splash screen has been created
  //before trying to close it
  while (!m_SplashScreen.GetSafeHwnd());

  m_SplashScreen.SetOKToClose();
  m_SplashScreen.SendMessage(WM_CLOSE);

}

void CSplashThread::SetBitmapToUse(const CString& sFilename)
{
  m_SplashScreen.SetBitmapToUse(sFilename);
}

void CSplashThread::SetBitmapToUse(UINT nResourceID)
{
  m_SplashScreen.SetBitmapToUse(nResourceID);
}

void CSplashThread::SetBitmapToUse(LPCTSTR pszResourceName)
{
  m_SplashScreen.SetBitmapToUse(pszResourceName);
}

// ---------------------------------------------------------
// 名称: SetShowMode()
// 功能:设置动态菲屏显示效果,具有下面属性:
//		(-1	-- 随机显示,		0	-- 水平交错效果,		1	-- 垂直交错效果,
//		 2	-- 水平百叶窗效果,	3	-- 垂直百叶窗效果,		4	-- 随机积木效果,
//		 5	-- 滤镜效果,		6	-- 垂直平分扫描,		7	-- 水平平分扫描,
//		 8	-- 水平交叉移动,	9	-- 垂直交叉移动,		10	-- 垂直栅条效果,
//		 11	-- 水平栅条效果,	12	-- 环形扫锚效果,		13	-- 缩放效果,
//		 14	-- 矩形扩张效果,	15	-- 椭圆扩张效果,		16	-- 圆角矩形扩张,
//		 17	-- 渐显效果,		18	-- 渐隐效果,			19	-- 正常显示)	
// 参数: nShowMode -- 显示效果,参见功能部分
// 返回: 无
// 编写: 徐景周(jingzhou_xu@163.net)
// 组织: 未来工作室(Future Studio)
// 日期: 2002.1.8
// ---------------------------------------------------------
void CSplashThread::SetShowMode(int nShowMode)   
{
	m_SplashScreen.SetShowMode(nShowMode);
}

BEGIN_MESSAGE_MAP(CSplashWnd, CWnd)
  //{{AFX_MSG_MAP(CSplashWnd)
  ON_WM_CREATE()
  ON_WM_PAINT()
  ON_WM_LBUTTONDOWN()
  ON_WM_CLOSE()
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// ---------------------------------------------------------
// 名称: CSplashWnd()
// 功能:构造涵数初始化工作
// 参数: 无
// 返回: 无
// 编写: 徐景周(jingzhou_xu@163.net)
// 组织: 未来工作室(Future Studio)
// 日期: 2002.1.8
// ---------------------------------------------------------
CSplashWnd::CSplashWnd()
{
	m_bOKToClose = FALSE;
	m_nHeight = 0;
	m_nWidth = 0;

	// 默认菲屏显示效果为随机显示	 
	m_nShowMode = -1;       
}

// ---------------------------------------------------------
// 名称: ~CSplashWnd()
// 功能:退出时清扫工作
// 参数: 无
// 返回: 无
// 编写: 徐景周(jingzhou_xu@163.net)
// 组织: 未来工作室(Future Studio)
// 日期: 2002.1.8
// ---------------------------------------------------------
CSplashWnd::~CSplashWnd()
{
  if(NULL != m_bmpDst)
	  DeleteObject(m_bmpDst);
  if(NULL != m_bmpSrc)
	  DeleteObject(m_bmpSrc);
  // 关闭DrawDib库
  if (m_hDrawDib)
  {
	  DrawDibClose(m_hDrawDib);
	  m_hDrawDib = NULL;
  }

  //destroy our invisible owner when we're done
  if (m_wndOwner.m_hWnd != NULL)
    m_wndOwner.DestroyWindow();
}

BOOL CSplashWnd::LoadBitmap()
{     
  //Use LoadImage to get the image loaded into a DIBSection
  HBITMAP hBitmap;
  if (m_bUseFile)
    hBitmap = (HBITMAP) ::LoadImage(NULL, m_sFilename, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
  else
    hBitmap = (HBITMAP) ::LoadImage(AfxGetResourceHandle(), m_pszResourceName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE);

  //Check that we could load it up  
  if (hBitmap == NULL)       
    return FALSE;

  //Get the width and height of the DIBSection
  BITMAP bm;
  GetObject(hBitmap, sizeof(BITMAP), &bm);
  m_nHeight = bm.bmHeight;
  m_nWidth = bm.bmWidth;

  //Covert from the SDK bitmap handle to the MFC equivalent
  m_Bitmap.Attach(hBitmap);

  return TRUE;   
}

void CSplashWnd::CreatePaletteFromBitmap()
{
  //Get the color depth of the DIBSection
  BITMAP bm;
  m_Bitmap.GetObject(sizeof(BITMAP), &bm);

  //If the DIBSection is 256 color or less, it has a color table
  if ((bm.bmBitsPixel * bm.bmPlanes) <= 8 )     
  {
    //Create a memory DC and select the DIBSection into it
    CDC memDC;
    memDC.CreateCompatibleDC(NULL);
    CBitmap* pOldBitmap = memDC.SelectObject(&m_Bitmap);

    //Get the DIBSection's color table
    RGBQUAD rgb[256];
    ::GetDIBColorTable(memDC.m_hDC, 0, 256, rgb);

    //Create a palette from the color table
    LPLOGPALETTE pLogPal = (LPLOGPALETTE) new BYTE[sizeof(LOGPALETTE) + (256*sizeof(PALETTEENTRY))];
    pLogPal->palVersion = 0x300;       
    pLogPal->palNumEntries = 256;

    for (WORD i=0; i<256; i++)       
    {
      pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed;
      pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen;
      pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue;
      pLogPal->palPalEntry[i].peFlags = 0;
    }
    VERIFY(m_Palette.CreatePalette(pLogPal));
    
    //Clean up
    delete pLogPal;
    memDC.SelectObject(pOldBitmap);

	//zwh Adding,2002.6.20 
	memDC.DeleteDC();
  }
  else  //It has no color table, so use a halftone palette     
  {
    CDC* pRefDC = GetDC();
    m_Palette.CreateHalftonePalette(pRefDC);
    ReleaseDC(pRefDC);     
  }     
}

// ---------------------------------------------------------
// 名称: Create()
// 功能:菲屏创建初始化工作
// 参数: 无
// 返回: TRUE -- 成功, FALSE -- 失败
// 编写: 徐景周(jingzhou_xu@163.net)
// 组织: 未来工作室(Future Studio)
// 日期: 2002.1.8
// ---------------------------------------------------------
BOOL CSplashWnd::Create()
{                   
  //Load up the bitmap from file or from resource
  VERIFY(LoadBitmap());

  //Modify the owner window of the splash screen to be an invisible WS_POPUP 
  //window so that the splash screen does not appear in the task bar
  LPCTSTR pszWndClass = AfxRegisterWndClass(0);
  VERIFY(m_wndOwner.CreateEx(0, pszWndClass, _T(""), WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, 0));

  //Create this window
  pszWndClass = AfxRegisterWndClass(0, AfxGetApp()->LoadStandardCursor(IDC_ARROW));
  VERIFY(CreateEx(0, pszWndClass, _T(""), WS_POPUP | WS_VISIBLE, 0, 0, m_nWidth, m_nHeight, m_wndOwner.GetSafeHwnd(), NULL));

  //Create the palette, We need to do this after the window is created because
  //we may need to access the DC associated with it
  CreatePaletteFromBitmap();

  //realize the bitmap's palette into the DC
  OnQueryNewPalette();

// ----------------------------------------------------------------------------------
  // 下面部分初始化位图渐隐、渐显效果数据,jingzhou xu
  m_bmpSrc		= NULL;
  m_bmpDst		= NULL;

  // 打开DrawDib库
  m_hDrawDib = DrawDibOpen();

  HDC hMemDC	= CreateCompatibleDC(NULL);
  if(hMemDC)
  {
	  // 创建二个32位深度位图,源和目标
	  BITMAPINFOHEADER RGB32BITSBITMAPINFO =
	  {
			sizeof(BITMAPINFOHEADER),
			m_nWidth, m_nHeight,
			1, 32, BI_RGB,
			0,0,0,0,0
	  };

	  m_bmpSrc	= CreateDIBSection(	hMemDC,
									(BITMAPINFO*)&RGB32BITSBITMAPINFO,
									DIB_RGB_COLORS,(VOID**)&m_clrSrc,
									NULL,0);
	  m_bmpDst	= CreateDIBSection(	hMemDC,
									(BITMAPINFO*)&RGB32BITSBITMAPINFO,
									DIB_RGB_COLORS,(VOID**)&m_clrDst,
									NULL,0);
	  
	  if(m_bmpSrc && m_bmpDst)
	  {
			HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, m_bmpSrc);
			HDC		hDC		= CreateCompatibleDC(hMemDC);
			if(hDC)
			{
				// 将要显示的菲屏位图分别复制到创建的32位色源和目标位图中
				HBITMAP hOldBmp2 = (HBITMAP)SelectObject(hDC, (HBITMAP)m_Bitmap);
				BitBlt(hMemDC, 0, 0, m_nWidth, m_nHeight, hDC, 0, 0, SRCCOPY);

				SelectObject(hMemDC, m_bmpDst);
				BitBlt(hMemDC, 0, 0, m_nWidth, m_nHeight, hDC, 0, 0, SRCCOPY);

				// 恢复及清扫工作
				SelectObject(hDC, hOldBmp2);
				DeleteDC(hDC);
			}
			SelectObject(hMemDC, hOldBmp);
	  }
	  DeleteDC(hMemDC);
  }
// ----------------------------------------------------------------------------------

  return TRUE;
}

int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CWnd::OnCreate(lpCreateStruct) == -1)
    return -1;

  //Center the splash window on the screen
  CenterWindow();

  return 0;
}

// ---------------------------------------------------------
// 名称: OnPaint()
// 功能:绘制动态菲屏显示效果,具有下面属性:
//		(-1	-- 随机显示,		0	-- 水平交错效果,		1	-- 垂直交错效果,
//		 2	-- 水平百叶窗效果,	3	-- 垂直百叶窗效果,		4	-- 随机积木效果,
//		 5	-- 滤镜效果,		6	-- 垂直平分扫描,		7	-- 水平平分扫描,
//		 8	-- 水平交叉移动,	9	-- 垂直交叉移动,		10	-- 垂直栅条效果,
//		 11	-- 水平栅条效果,	12	-- 环形扫锚效果,		13	-- 缩放效果,
//		 14	-- 矩形扩张效果,	15	-- 椭圆扩张效果,		16	-- 圆角矩形扩张,
//		 17	-- 渐显效果,		18	-- 渐隐效果,			19	-- 正常显示)		 		 
// 参数: 无
// 返回: 无
// 编写: 徐景周(jingzhou_xu@163.net)
// 组织: 未来工作室(Future Studio)
// 日期: 2002.1.8
// ---------------------------------------------------------
void CSplashWnd::OnPaint()
{
	CPaintDC dc(this);

	// 选择调色板及位图到DC中
	CDC memDC;
	memDC.CreateCompatibleDC(&dc);
	CBitmap* pOldBitmap = memDC.SelectObject(&m_Bitmap);
	CPalette* pOldPalette = dc.SelectPalette(&m_Palette, FALSE);
	dc.RealizePalette();

	//---------------------------------------------------------
	// 以下部分为动态显示菲屏效果代码,jingzhou xu 
	int i,j,step,stepx,stepy,dispnum,x,y; 
	BOOL bDone, bQuit;

	if(m_nShowMode == -1)						// 随机菲屏效果显示
	{
		srand((unsigned)time(NULL)); 
		m_nShowMode = rand()%20;				// 随机选择已有20种中的一种效果
	}

	switch(m_nShowMode)
	{
	case 0:
		// 一、水平交错效果算法
		for( i=0; i<=m_nHeight; i+=2 ) 
		{
			j = i; 
			while(j>0) 
			{
				dc.StretchBlt(					// 奇数,由上至下 
					0,j-1,						// 目标设备逻辑横、纵坐标 
					m_nWidth,1,					// 显示位图的像素宽、高度 
					&memDC,						// 源位图设备对象 
					0,m_nHeight-(i-j-1),		// 源位图的起始横、纵坐标 
					m_nWidth,1,					// 源位图的像素宽、高度 
					SRCCOPY); 
				
				dc.StretchBlt(					// 偶数,由下至上 
					0,m_nHeight-j,				// 目标设备逻辑横、纵坐标 
					m_nWidth,1, 				// 显示位图的像素宽、高度 
					&memDC, 					// 源位图设备对象 
					0,i-j, 						// 源位图的起始横、纵坐标 
					m_nWidth,1, 				// 源位图的像素宽、高度 
					SRCCOPY); 
				j-=2; 
			} 
			Sleep(20);
		} 
		dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
		Sleep(500);

		break;
	case 1:
		// 二、垂直交错效果算法
		for( i=0; i<=m_nWidth; i+=2 ) 
		{
			j = i; 
			while(j>0) 
			{
				dc.StretchBlt(					// 奇数,由左至右 
					j-1,0,						// 目标设备逻辑横、纵坐标 
					1,m_nHeight,				// 显示位图的像素宽、高度 
					&memDC,						// 源位图设备对象 		
					m_nWidth-(i-j-1),0,			// 源位图的起始横、纵坐标 
					1,m_nHeight,				// 源位图的像素宽、高度 
					SRCCOPY); 
				
				dc.StretchBlt(					// 偶数,由右至左 
					m_nWidth-j, 0,				// 目标设备逻辑横、纵坐标 
					1, m_nHeight,				// 显示位图的像素宽、高度 
					&memDC,						// 源位图设备对象 
					i-j, 0,						// 源位图的起始横、纵坐标 
					1, m_nHeight,				// 源位图的像素宽、高度 
					SRCCOPY); 
				j-=2; 
			} 
			Sleep(20);
		} 
		dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
		Sleep(500);

		break;
	case 2:
		// 三、水平百叶窗效果算法
		step=m_nHeight/15; 
		for ( i=0; i<=step; ++i ) 
		{
			for ( j=0; j<15; ++j ) 
				dc.StretchBlt( 
				0,j*step+i,						// 目标设备逻辑横、纵坐标 
				m_nWidth,1,						// 显示位图的像素宽、高度 
				&memDC, 						// 源位图设备对象 
				0,j*step+i, 					// 源位图的起始横、纵坐标 
				m_nWidth,1, 					// 源位图的像素宽、高度 
				SRCCOPY); 
			
			Sleep(30); 
		}

		break;
	case 3:
		// 四、垂直百叶窗效果算法
		step=m_nWidth/15; 
		for ( i=0; i<=step; ++i ) 
		{
			for ( j=0; j<15; ++j ) 
				dc.StretchBlt( 
				j*step+i,0, 					// 目标设备逻辑横、纵坐标 
				1,m_nHeight,					// 显示位图的像素宽、高度 
				&memDC, 						// 源位图设备对象 
				j*step+i,0, 					// 源位图的起始横、纵坐标 
				1, m_nHeight,					// 源位图的像素宽、高度 
				SRCCOPY); 
			
			Sleep(30); 
		}

		break;
	case 4:
		// 五、随机积木效果算法
		int pxy[10][10];						// 碎片数
		for ( i=0; i<10; ++i ) 
			for ( j=0; j<10; ++j ) 
				pxy[i][j]=0; 
		stepx=m_nWidth/10; 
		stepy=m_nHeight/10; 
		srand( (unsigned)time( NULL ) ); 
		dispnum=0; 
		while(1) 
		{ 
			x=rand() % 10; 
			y=rand() % 10; 
			if ( pxy[x][y] )					// 已经显示过,跳过
				continue; 
			pxy[x][y]=1;						// 当前显示的置1
			dc.StretchBlt( 
				x*stepx, y*stepy,				// 目标设备逻辑横、纵坐标 
				stepx,stepy, 					// 显示位图的像素宽、高度 
				&memDC, 						// 源位图设备对象 
				x*stepx, y*stepy, 				// 源位图的起始横、纵坐标 
				stepx,stepy, 					// 源位图的像素宽、高度 
				SRCCOPY); 
			dispnum++; 

			if ( dispnum >=100 )				// 是否显示完
				break; 

			Sleep(10); 
		} 
		Sleep(300);

		break;
	case 5:
		// 六、滤镜效果算法
		int i,j; 
		for (i=0; i<=m_nHeight; ++i) 
		{
			for (j=0; j<=m_nHeight-i; ++j) 
				dc.StretchBlt(0, j, m_nWidth, 1, &memDC, 0, m_nHeight-i, m_nWidth,1, SRCCOPY);
			
			Sleep(10); 
		} 
		Sleep(300);

		break;
	case 6:
		// 七、垂直平分扫描算法
		bDone	= FALSE;
		i		= 0;
		while(!bDone)
		{
			// 大于高度一半时,置结束标志为真
			if(i > (m_nHeight+1)/2)
			{
				i		= (m_nHeight+1)/2;
				bDone	= TRUE;
			}
			
			// 上半部分从上到下,一次5个像素高度
			dc.StretchBlt(0, i, m_nWidth, 5, &memDC, 0, i, m_nWidth, 5, SRCCOPY);
			// 下半部分从下到上,一次5个像素高度
			dc.StretchBlt(0, m_nHeight-i, m_nWidth, 5, &memDC, 0, m_nHeight-i, m_nWidth, 5, SRCCOPY);
			
			i += 5;

			Sleep(30); 
		}

		break;
	case 7:
		// 八、水平平分扫描算法
		bDone	= FALSE;
		i		= 0;
		while(!bDone)
		{
			// 大于宽度一半时,置结束标志为真
			if(i > (m_nWidth+1)/2)
			{
				i		= (m_nWidth+1)/2;
				bDone	= TRUE;
			}
			
			// 左半部分从左到右,一次5个像素宽度
			dc.StretchBlt(i, 0, 5, m_nHeight, &memDC, i, 0, 5, m_nHeight, SRCCOPY);
			// 右半部分从右到左,一次5个像素宽度
			dc.StretchBlt(m_nWidth-i, 0, 5, m_nHeight, &memDC, m_nWidth-i, 0, 5, m_nHeight, SRCCOPY);
			
			i += 5;

			Sleep(30); 
		}

		break;
	case 8:
		// 九、水平交叉移动算法
		bDone	= FALSE;
		i		= 0;
		while(!bDone)
		{
			// 大于宽度时,置结束标志为真
			if(i > m_nWidth)
			{
				i		= m_nWidth;
				bDone	= TRUE;
			}
			
			// 上半部分从右到左,一次移动10个像素宽度
			dc.StretchBlt(0, 0, i, (m_nHeight+1)/2, &memDC, m_nWidth-i, 0, i, (m_nHeight+1)/2, SRCCOPY);
			// 下半部分从左到右,一次移动10个像素宽度
			dc.StretchBlt(m_nWidth-i, (m_nHeight+1)/2, i, (m_nHeight+1)/2, &memDC, 0, (m_nHeight+1)/2, i, (m_nHeight+1)/2, SRCCOPY);
			
			i += 10;

			Sleep(30); 
		}

		break;
	case 9:
		// 十、垂直交叉移动算法
		bDone	= FALSE;
		i		= 0;
		while(!bDone)
		{
			// 大于高度时,置结束标志为真
			if(i > m_nHeight)
			{
				i		= m_nHeight;
				bDone	= TRUE;
			}
			
			// 左半部分从底到顶,一次移动10个像素宽度
			dc.StretchBlt(0, 0, (m_nWidth+1)/2, i, &memDC, 0, m_nHeight-i, (m_nWidth+1)/2, i, SRCCOPY);
			// 右半部分从顶到底,一次移动10个像素宽度
			dc.StretchBlt((m_nWidth+1)/2, m_nHeight-i, m_nWidth, i, &memDC, (m_nWidth+1)/2, 0, m_nWidth, i, SRCCOPY);
			
			i += 10;

			Sleep(30); 
		}

		break;
	case 10:
		// 十一、垂直栅条算法
		bDone	= FALSE;
		i		= 0;
		
		while(!bDone)
		{
			// 大于高度时,置结束标志为真
			if(i > m_nHeight)
			{
				i		= m_nHeight;
				bDone	= TRUE;
			}
			
			bQuit		= FALSE;
			j			= 0;

			while(!bQuit)
			{
				// 大于宽度,置退出内循环标志为真
				if(j > m_nWidth)
				{
					j		= m_nWidth;
					bQuit	= TRUE;
				}

				// 分为多个纵向垂直小条,从左向右,奇数向下移动,偶数向上移动
				dc.StretchBlt(j, 0, 10, i, &memDC, j, m_nHeight-i, 10, i, SRCCOPY);
				j += 10;

				// 大于宽度,置退出内循环标志为真
				if(j > m_nWidth)
				{
					j		= m_nWidth;
					bQuit	= TRUE;
				}

				// 分为多个纵向垂直小条,从左向右,奇数向下移动,偶数向上移动
				dc.StretchBlt(j, m_nHeight-i, 10, i, &memDC, j, 0, 10, i, SRCCOPY);
				j += 10;
			}

			++i;

			Sleep(20); 
		}
		Sleep(500);

		break;
	case 11:
		// 十二、水平栅条算法
		bDone	= FALSE;
		i		= 0;
		
		while(!bDone)
		{
			// 大于宽度时,置结束标志为真
			if(i > m_nWidth)
			{
				i		= m_nWidth;
				bDone	= TRUE;
			}
			
			bQuit		= FALSE;
			j			= 0;

			while(!bQuit)
			{
				// 大于高度,置退出内循环标志为真
				if(j > m_nHeight)
				{
					j		= m_nHeight;
					bQuit	= TRUE;
				}

				// 分为多个横向水平小条,从上向下,奇数向左移动,偶数向右移动
				dc.StretchBlt(0, j, i, 10, &memDC, m_nWidth-i, j, i, 10, SRCCOPY);
				j += 10;

				// 大于高度,置退出内循环标志为真
				if(j > m_nHeight)
				{
					j		= m_nHeight;
					bQuit	= TRUE;
				}

				// 分为多个横向水平小条,从上向下,奇数向左移动,偶数向右移动
				dc.StretchBlt(m_nWidth-i, j, i, 10, &memDC, 0, j, i, 10, SRCCOPY);
				j += 10;
			}

			++i;

			Sleep(20); 
		}
		Sleep(500);

		break;
	case 12:
		{
			// 十三、环形扫锚效果算法
			int nCenterX,nCenterY;

			// 设置从中心点开始扫锚
			nCenterY = (m_nHeight+1)/2;
			nCenterX = (m_nWidth+1)/2;

			// 右上部分逐列向右扫锚
			for(i = 0; i < nCenterX; )
			{
				i += 10;
				if(i > nCenterX)
					i	= nCenterX;
				
				dc.BitBlt(nCenterX, 0, i, nCenterY, &memDC, nCenterX, 0, SRCCOPY);
				
				Sleep(30);
			}

			// 右下部分逐行向下扫锚
			for(i = 0; i < nCenterY; )
			{
				i += 10;
				if(i > nCenterY)
					i	= nCenterY;
				
				dc.BitBlt(nCenterX, nCenterY, nCenterX, i, &memDC, nCenterX, nCenterY, SRCCOPY);
				
				Sleep(30);
			}

			// 左下部分逐列向左扫锚
			for(i = nCenterX; i > 0; )
			{
				i -= 10;
				if(i < 0)
					i	= 0;
				
				dc.BitBlt(i, nCenterY, nCenterX-i, nCenterY, &memDC, i, nCenterY, SRCCOPY);
				
				Sleep(30);
			}

			// 左上部分逐行向上扫锚
			for(i = nCenterY; i > 0; )
			{
				i -= 10;
				if(i < 0)
					i	= 0;
				
				dc.BitBlt(0, i, nCenterX, nCenterY-i, &memDC, 0, i, SRCCOPY);
				
				Sleep(30);
			}
		}

		break;
	case 13:
		{
			// 十四、缩放效果算法
			bDone			= FALSE;

			int nCenterX,nCenterY;
			// 设置中心点
			nCenterY		= (m_nHeight+1)/2;
			nCenterX		= (m_nWidth+1)/2;

			double dbScale	= 0.0;
			while(!bDone)
			{
				dbScale		+= 0.1; 
				// 越界处理
				if(dbScale >= 1.0)		
				{
					dbScale	= 1.0;
					bDone	= TRUE;
				}
				
				// 由内向外,逐渐放大
				dc.StretchBlt(nCenterX-static_cast<int>((m_nWidth*dbScale)/2), 
					nCenterY-static_cast<int>((m_nHeight*dbScale)/2), 
					static_cast<int>(m_nWidth*dbScale), static_cast<int>(m_nHeight*dbScale),
					&memDC, 0, 0, m_nWidth, m_nHeight, SRCCOPY);
				
				Sleep(50); 
			}
		}

		break;
	case 14:
		{
			// 十五、矩形扩张效果算法
			bDone	= FALSE;
			int left,right,top,bottom;

			// 设置从中心点开始扩张
			top = bottom = (m_nHeight+1)/2;
			left = right = (m_nWidth+1)/2;
			while(!bDone)
			{
				// 越界处理
				if(m_nHeight > m_nWidth)		// 高大于宽时
				{
					if(top < 0 && bottom > m_nHeight)
					{
						top		= 0;
						bottom	= m_nHeight;
						bDone	= TRUE;
					}
					else if(top < 0)
						top		= 0;
					else if(bottom > m_nHeight)
						bottom	= m_nHeight;

					if(left < 0)
						left	= 0;
					if(right > m_nWidth)
						right	= m_nWidth;
				}
				else							// 宽大于等于高时
				{
					if(left < 0 && right > m_nWidth)
					{
						left	= 0;
						right	= m_nWidth;
						bDone	= TRUE;
					}
					else if(left < 0)
						left	= 0;
					else if(right > m_nWidth)
						right	= m_nWidth;

					if(top < 0)
						top		= 0;
					if(bottom > m_nHeight)
						bottom	= m_nHeight;
				}
				
				// 由内向外,逐渐扩张
				dc.StretchBlt(left, top, right - left, bottom - top, &memDC, left, top, right - left, bottom - top, SRCCOPY);
				
				left	-= 10;
				right	+= 10;
				top		-= 10;
				bottom	+= 10;
				
				Sleep(50); 
			}
		}

		break;
	case 15:
		{
			// 十六、椭圆扩张效果算法
			bDone	= FALSE;
			int nCenterX,nCenterY;

			// 设置从中心点开始扩张
			nCenterY = (m_nHeight+1)/2;
			nCenterX = (m_nWidth+1)/2;

			CRgn  WinRgn;
			while(!bDone)
			{
				// 越界处理
				if(m_nHeight > m_nWidth)		// 高大于宽时
				{
					if(nCenterY < 0)
					{
						nCenterY	= 0;
						bDone		= TRUE;
					}

					if(nCenterX < 0)
						nCenterX	= 0;
				}
				else							// 宽大于等于高时
				{
					if(nCenterX < 0)
					{
						nCenterX	= 0;
						bDone		= TRUE;
					}

					if(nCenterY < 0)
						nCenterY	= 0;
				}
				
				// 扩张速度
				nCenterX	-= 5;
				nCenterY	-= 5;

				// 由内向外,逐渐扩张
				VERIFY(WinRgn.CreateEllipticRgn(nCenterX, nCenterY,
										m_nWidth - nCenterX, m_nHeight - nCenterY));
				VERIFY(SetWindowRgn(WinRgn , FALSE));

				dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);

				// 清扫工作
				WinRgn.DeleteObject();

				Sleep(50); 
			}

			// 显示整幅图
			SetWindowRgn(NULL , TRUE);
			dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
		}

		break;
	case 16:
		{
			// 十七、圆角矩形扩张效果算法
			bDone	= FALSE;
			int nCenterX,nCenterY;

			// 设置从中心点开始扩张
			nCenterY = (m_nHeight+1)/2;
			nCenterX = (m_nWidth+1)/2;

			// 圆角宽、高弧度
			int nWidthRound, nHeightRound;
			nWidthRound = nHeightRound = 100;

			CRgn  WinRgn;
			while(!bDone)
			{
				// 越界处理
				if(m_nHeight > m_nWidth)		// 高大于宽时
				{
					if(nCenterY < 0)
					{
						nCenterY	= 0;
						bDone		= TRUE;
					}

					if(nCenterX < 0)
						nCenterX	= 0;
				}
				else							// 宽大于等于高时
				{
					if(nCenterX < 0)
					{
						nCenterX	= 0;
						bDone		= TRUE;
					}

					if(nCenterY < 0)
						nCenterY	= 0;
				}
				
				// 扩张速度
				nCenterX	-= 5;
				nCenterY	-= 5;

				// 由内向外,逐渐扩张
				VERIFY(WinRgn.CreateRoundRectRgn(nCenterX, nCenterY,
										m_nWidth - nCenterX, m_nHeight - nCenterY, 
										nWidthRound, nHeightRound));
				VERIFY(SetWindowRgn(WinRgn , FALSE));

				dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);

				// 清扫工作
				WinRgn.DeleteObject();

				Sleep(50); 
			}

			// 显示整幅图
			SetWindowRgn(NULL , TRUE);
			dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);
		}

		break;
	case 17:
		// 十八、渐显效果算法
		{
			if(NULL == m_bmpSrc || NULL == m_hDrawDib)
				return;
			
			// 清空目标32位位图数据
			memset((void*)m_clrDst, 0, m_nWidth*m_nHeight*sizeof(COLORREF));

			BOOL bDone = FALSE;
			int i,j;
			BYTE r,g,b,r0,g0,b0;

			BITMAPINFOHEADER RGB32BITSBITMAPINFO =
			{
				sizeof(BITMAPINFOHEADER),
					m_nWidth, m_nHeight,
					1, 32, BI_RGB,
					0,0,0,0,0
			};

			// 初始化DrawDib库
			DrawDibRealize(m_hDrawDib, dc.GetSafeHdc(), TRUE);

			while(!bDone)
			{
				bDone = TRUE;
				// 位图中每个像素颜色从黑色逐渐递增到原色为止
				for(i = 0; i < m_nWidth; ++i)
				{
					for(j = 0; j < m_nHeight; ++j)
					{
						r	= GetRValue(m_clrDst[i+j*m_nWidth]);
						g	= GetGValue(m_clrDst[i+j*m_nWidth]);
						b	= GetBValue(m_clrDst[i+j*m_nWidth]);
						r0	= GetRValue(m_clrSrc[i+j*m_nWidth]);
						g0	= GetGValue(m_clrSrc[i+j*m_nWidth]);
						b0	= GetBValue(m_clrSrc[i+j*m_nWidth]);

						r = r+10<r0 ? r+10 : r0;
						g = g+10<g0 ? g+10 : g0;
						b = b+10<b0 ? b+10 : b0;
						
						m_clrDst[i+j*m_nWidth] = RGB(r,g,b);

						if((r<r0) || (g<g0) ||(b<b0))
							bDone = FALSE;
					}
				}

				// 绘制颜色值处理后的位图(从黑到原色来实现渐显效果)
				DrawDibDraw(m_hDrawDib, dc.GetSafeHdc(), 0, 0, m_nWidth, m_nHeight, 
							&RGB32BITSBITMAPINFO,(LPVOID)m_clrDst, 0, 0, m_nWidth, 
							m_nHeight, DDF_BACKGROUNDPAL);

				Sleep(50); 
			}

			Sleep(300);
		}

		break;
	case 18:
		// 十九、渐隐效果算法
		{
			if(NULL == m_bmpSrc || NULL == m_hDrawDib)
				return;
			
			// 复制源位图数据到目标位图中
			memcpy((void*)m_clrDst, (void*)m_clrSrc, m_nWidth*m_nHeight*sizeof(COLORREF));

			BOOL bDone = FALSE;
			int i,j;
			BYTE r,g,b;

			BITMAPINFOHEADER RGB32BITSBITMAPINFO =
			{
				sizeof(BITMAPINFOHEADER),
					m_nWidth, m_nHeight,
					1, 32, BI_RGB,
					0,0,0,0,0
			};

			// 初始化DrawDib库
			DrawDibRealize(m_hDrawDib, dc.GetSafeHdc(), TRUE);

			// 先绘制源图,然后再逐渐将它转换为黑色来实现渐隐效果
			DrawDibDraw(m_hDrawDib, dc.GetSafeHdc(), 0, 0, m_nWidth, m_nHeight, 
							&RGB32BITSBITMAPINFO,(LPVOID)m_clrDst, 0, 0, m_nWidth, 
							m_nHeight, DDF_BACKGROUNDPAL);

			while(!bDone)
			{
				bDone = TRUE;
				// 位图中每个像素颜色从原色逐渐递减到黑色为止
				for(i = 0; i < m_nWidth; ++i)
				{
					for(j = 0; j < m_nHeight; ++j)
					{
						r	= GetRValue(m_clrDst[i+j*m_nWidth]);
						g	= GetGValue(m_clrDst[i+j*m_nWidth]);
						b	= GetBValue(m_clrDst[i+j*m_nWidth]);

						r = r-10>0 ? r-10 : 0;
						g = g-10>0 ? g-10 : 0;
						b = b-10>0 ? b-10 : 0;
						
						m_clrDst[i+j*m_nWidth] = RGB(r,g,b);

						// 当颜色接近于纯黑色时退出
						if((r>10) || (g>10) ||(b>10))
							bDone = FALSE;
					}
				}

				// 绘制颜色值处理后的位图(从黑到原色来实现渐显效果)
				DrawDibDraw(m_hDrawDib, dc.GetSafeHdc(), 0, 0, m_nWidth, m_nHeight, 
							&RGB32BITSBITMAPINFO,(LPVOID)m_clrDst, 0, 0, m_nWidth, 
							m_nHeight, DDF_BACKGROUNDPAL);

				Sleep(50); 
			}
		}

		break;
	default:
		// 其它、正常显示
		dc.BitBlt(0, 0, m_nWidth, m_nHeight, &memDC, 0, 0, SRCCOPY);

		break;
	}
	//---------------------------------------------------------

	// 恢复及清扫工作
	memDC.SelectObject(pOldBitmap);         
	dc.SelectPalette(pOldPalette, FALSE);

	memDC.DeleteDC();
}

//This message is an optional extra, If you do not want the splash screen
//to be not be dragable then remove this function and its message map entry
void CSplashWnd::OnLButtonDown(UINT nFlags, CPoint point) 
{

}

void CSplashWnd::OnClose() 
{
  if (m_bOKToClose) 
    CWnd::OnClose();

//   AfxEndThread(0);
}

BOOL CSplashWnd::SelRelPal(BOOL bForceBkgnd)
{
  // We are going active, so realize our palette.
  CDC* pDC = GetDC();

  CPalette* pOldPal = pDC->SelectPalette(&m_Palette, bForceBkgnd);
  UINT u = pDC->RealizePalette();
  pDC->SelectPalette(pOldPal, TRUE);
  pDC->RealizePalette();

  ReleaseDC(pDC);

  // If any colors have changed or we are in the
  // background, repaint the lot.
  if (u || bForceBkgnd) 
    InvalidateRect(NULL, TRUE); // Repaint.
  
  return (BOOL) u; // TRUE if some colors changed.
}

void CSplashWnd::OnPaletteChanged(CWnd* pFocusWnd)
{
  // See if the change was caused by us and ignore it if not.
  if (pFocusWnd != this) 
    SelRelPal(TRUE); // Realize in the background. 
}

BOOL CSplashWnd::OnQueryNewPalette()
{
  return SelRelPal(FALSE); // Realize in the foreground.
}

void CSplashWnd::SetBitmapToUse(const CString& sFilename)
{
  m_bUseFile = TRUE;
  m_sFilename = sFilename;
}

void CSplashWnd::SetBitmapToUse(UINT nResourceID)
{
  m_bUseFile = FALSE;
  m_pszResourceName = MAKEINTRESOURCE(nResourceID);
}

void CSplashWnd::SetBitmapToUse(LPCTSTR pszResourceName)
{
  m_bUseFile = FALSE;
  m_pszResourceName = pszResourceName;
}


BOOL CSplashWnd::PreTranslateMessage(MSG* pMsg) 
{
	// If we get a keyboard or mouse message, hide the splash screen.
	if (pMsg->message == WM_KEYDOWN ||
	    pMsg->message == WM_SYSKEYDOWN ||
	    pMsg->message == WM_LBUTTONDOWN ||
	    pMsg->message == WM_RBUTTONDOWN ||
	    pMsg->message == WM_MBUTTONDOWN ||
	    pMsg->message == WM_NCLBUTTONDOWN ||
	    pMsg->message == WM_NCRBUTTONDOWN ||
	    pMsg->message == WM_NCMBUTTONDOWN)
	{
//		SendMessage(WM_CLOSE);
//		return TRUE;	// message handled here
	}	

	return CWnd::PreTranslateMessage(pMsg);
}