www.gusucode.com > 一个VC++软件启动动态闪屏特效代码-源码程序 > 一个VC++软件启动动态闪屏特效代码-源码程序/code/YuWnd.cpp

    /*
* Copyright (c) 2004,公子雨
* 文件名称:YuWnd.cpp
* 文件标识:闪屏效果源文件
* 介    绍:由屏保得到的灵感而写,献给可怜的公子雨
* 当前版本:1.0
* 作    者:公子雨
* 完成日期:2004年3月2日
*/

// YuWnd.cpp : implementation file
// download by http://www.NewXing.com

#include "stdafx.h"
#include "YuWnd.h"

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

/////////////////////////////////////////////////////////////////////////////
// CYuWnd

CYuWnd::CYuWnd()
{
   	m_bitmap.LoadBitmap(IDB_YU);	//拷贝资源位图
	m_bitmap.GetBitmap(&bm);		//得到位图结构中的大小信息
	m_nXStep = 20;					//X方向的步长
	m_nYStep = 1;					//Y方向的步长,步长决定了下一点的位置
	m_nBlockNum = 200;				//将图片在X,Y方向均分为多少份
	m_nDelay = 10;					//绘制完一组点(m_nBlockNum个)后的延时
	m_bDirection = TRUE;			//表示第一个点从左上角开始
}

CYuWnd::~CYuWnd()
{

}

BEGIN_MESSAGE_MAP(CYuWnd, CWnd)
	//{{AFX_MSG_MAP(CYuWnd)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CYuWnd message handlers

void CYuWnd::CreatYuWnd()
{
	//建立大小与位图大小相同的窗口
	CreateEx(0,
	AfxRegisterWndClass(0,AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
						"YuWindow",
						WS_POPUP,
						0,0,bm.bmWidth,bm.bmHeight,
						NULL,
						NULL,
						NULL );
	// 隐藏TitleBar
//	ModifyStyle(WS_CAPTION, 0, SWP_FRAMECHANGED);
	// 显示TitleBar
	//ModifyStyle(0, WS_CAPTION, SWP_FRAMECHANGED);
}



void CYuWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	if ( m_bDirection )
	{
		PointSlpash();
	}
	else
	{
		PointSlpashBottom();
	}
	// Do not call CWnd::OnPaint() for painting messages
}


void CYuWnd::PointSlpash()
{
	CClientDC dc(this);
	MemDC.CreateCompatibleDC(NULL);//建立一个和dc兼容的内存DC放置位图
	old_bitmap=MemDC.SelectObject(&m_bitmap);//将创建的位图选入内存DC

	int i,j,stepx,stepy,dispnum,x,y; 
//	int points[200][200];      //数组记录已显示过的数据组 

//	for ( i=0; i<m_nBlockNum; i++ ) 
//		for ( j=0; j<m_nBlockNum; j++ ) 
//			points[i][j]=0; 
/*	图片的分块由图片尺寸决定,如800 X 600的,如要图片能完全显示出来则不应超过200(能被两个尺寸整除)
	否则StretchBlt()会“吞噬掉一部分像素”。
	因为StretchBlt()中的参数类型是int,:)
*/
	stepx = bm.bmWidth/m_nBlockNum; 
	stepy = bm.bmHeight/m_nBlockNum; 

	dispnum = 0; //记录已显示过的数据组的个数 

	x = 0;
	y = 0;
	
	for ( i=0; i<m_nBlockNum; i++ ) 
	{ 
		for ( j=0; j<m_nBlockNum; j++ )
		{
			//第一处调节
	//		if ( points[i][j] ) //如果为1,则已经显示了,跳出循环。
	//		{
	//			x++;
	//		}
			
			if ( x >= m_nBlockNum )
			{
				x -= m_nBlockNum;
			}
			if ( y >= m_nBlockNum )
			{
				y -= m_nBlockNum;
			}
		

//			points[x][y] = 1; //显示,设置为1
			dc.StretchBlt( 
						x*stepx, y*stepy, //目标设备逻辑横、纵坐标 
						stepx,stepy, //显示位图的像素宽、高度 
						&MemDC, //位图内存设备对象 
						x*stepx, y*stepy, //位图的起始横、纵坐标 
						stepx,stepy, //位图的像素宽、高度 
						SRCCOPY); 

			dispnum++; 
			x += m_nXStep;
			y += m_nYStep;
		}
/*		此处x,y取值范围是
		(x\y)		0		i+1
		
		0			否		是			

		i+1			是		是
*/
		x = i+1;
		y = i+1;//0;//

		Sleep(m_nDelay); 
//		CString str;
//		str.Format("%d",dispnum);
//		AfxMessageBox(str);
	}

/*	
	第二处调节
	其实就是将图片完全显示出来,需不需要完全看个人。
	不过推荐不要,这样有可能实现模拟雾化的效果
*/

/*	for ( x=0; x<m_nBlockNum; x++ )
	{
		for ( y=0; y<m_nBlockNum; y++ )
		{
			if ( points[x][y] ) //如果为1,则已经显示了,跳出循环。
			{
				continue; 
			}
			points[x][y]=1; //显示,设置为1
			dc.StretchBlt( 
						x*stepx, y*stepy, //目标设备逻辑横、纵坐标 
						stepx,stepy, //显示位图的像素宽、高度 
						&MemDC, //位图内存设备对象 
						x*stepx, y*stepy, //位图的起始横、纵坐标 
						stepx,stepy, //位图的像素宽、高度 
						SRCCOPY);
		}
	}
*/	
	MemDC.SelectObject(old_bitmap);
	Sleep(300);
}

int CYuWnd::GetXStep()
{
	return m_nXStep;
}

int CYuWnd::GetYStep()
{
	return m_nYStep;
}

int CYuWnd::GetBlockNum()
{
	return m_nBlockNum;
}

void CYuWnd::SetXStep(int nStep)
{
	m_nXStep = nStep;
}

void CYuWnd::SetYStep(int nStep)
{
	m_nYStep = nStep;
}

void CYuWnd::SetBlockNum(int nBlockNum)
{
	m_nBlockNum = nBlockNum;
}

BOOL CYuWnd::GetDirection()
{
	return m_bDirection;
}

void CYuWnd::SetDirection(BOOL dir)
{
	m_bDirection = dir;
}

void CYuWnd::PointSlpashBottom()
{
	CClientDC dc(this);
	MemDC.CreateCompatibleDC(NULL);//建立一个和dc兼容的内存DC放置位图
	old_bitmap=MemDC.SelectObject(&m_bitmap);//将创建的位图选入内存DC

	int i,j,stepx,stepy,dispnum,x,y; 
//	int points[200][200];      //数组记录已显示过的数据组 

//	for ( i=0; i<m_nBlockNum; i++ ) 
//		for ( j=0; j<m_nBlockNum; j++ ) 
//			points[i][j]=0; 
/*	图片的分块由图片尺寸决定,如800 X 600的,如要图片能完全显示出来则不应超过200(能被两个尺寸整除)
	否则StretchBlt()会“吞噬掉一部分像素”。
	因为StretchBlt()中的参数类型是int,:)
*/
	stepx = bm.bmWidth/m_nBlockNum; 
	stepy = bm.bmHeight/m_nBlockNum; 

	dispnum = 0; //记录已显示过的数据组的个数 

	x = m_nBlockNum-1;
	y = m_nBlockNum-1;
	
	for ( i=m_nBlockNum; i>0; i-- ) 
	{ 
		for ( j=m_nBlockNum; j>0; j-- )
		{
			//第一处调节
	//		if ( points[i][j] ) //如果为1,则已经显示了,跳出循环。
	//		{
	//			x++;
	//		}
			
			if ( x <= 0 )
			{
				x += m_nBlockNum-1;
			}
			if ( y <= 0 )
			{
				y += m_nBlockNum-1;
			}
		

//			points[x][y] = 1; //显示,设置为1
			dc.StretchBlt( 
						x*stepx, y*stepy, //目标设备逻辑横、纵坐标 
						stepx,stepy, //显示位图的像素宽、高度 
						&MemDC, //位图内存设备对象 
						x*stepx, y*stepy, //位图的起始横、纵坐标 
						stepx,stepy, //位图的像素宽、高度 
						SRCCOPY); 

			dispnum++; 
			x -= m_nXStep;
			y -= m_nYStep;
		}
/*		此处x,y取值范围是
		(x\y)		0		i+1
		
		0			否		是			

		i+1			是		是
*/
		x = 0;//i+1;
		y = i+1;//0;//

		Sleep(m_nDelay); 
//		CString str;
//		str.Format("%d",dispnum);
//		AfxMessageBox(str);
	}

/*	
	第二处调节
	其实就是将图片完全显示出来,需不需要完全看个人。
	不过推荐不要,这样有可能实现模拟雾化的效果
*/

/*	for ( x=0; x<m_nBlockNum; x++ )
	{
		for ( y=0; y<m_nBlockNum; y++ )
		{
			if ( points[x][y] ) //如果为1,则已经显示了,跳出循环。
			{
				continue; 
			}
			points[x][y]=1; //显示,设置为1
			dc.StretchBlt( 
						x*stepx, y*stepy, //目标设备逻辑横、纵坐标 
						stepx,stepy, //显示位图的像素宽、高度 
						&MemDC, //位图内存设备对象 
						x*stepx, y*stepy, //位图的起始横、纵坐标 
						stepx,stepy, //位图的像素宽、高度 
						SRCCOPY);
		}
	}
*/	
	MemDC.SelectObject(old_bitmap);
	Sleep(300);
}

void CYuWnd::SetDelay(int nDelay)
{
	m_nDelay = nDelay;
}

int CYuWnd::GetDelay()
{
	return m_nDelay;
}