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; }