一、图片的平滑移动:
实现一副位图沿客户区上部y=50处下移,落入客户下部y=200逐渐消失;
步骤:
1、创建单文档应用程序(MFC AppWizard),工程名为SmoothMoving;
2、插入位图资源,可用上面数字1;
3、在CView类中增加对WM_CREATE和WM_TIMER的消息处理。
4、在WM_CREATE的消息响应函数中设置一个定时器,具体代码如下:
int CSmoothMovingView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(1,10,NULL);
return 0;
}
5、在WM_TIMER的消息响应函数中增加如下代码:
void CSmoothMovingView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//定义CBitmap类成员变量,变加载位图资源
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
//创建两个设备描述表,一个为当前设备描述表,一个为兼容设备描述表
//并让兼容设备描述表与当前设备描述表兼容,同时将位图变量加载于兼
//容设备描述表之中
CDC* pDC = GetDC();
CDC dcCompatible;
dcCompatible.CreateCompatibleDC(pDC);
dcCompatible.SelectObject(&bitmap);
//划两条线,位图从上面一条线移动到下面一条线
pDC->MoveTo(CPoint(0,100));
pDC->LineTo(CPoint(1000,100));
pDC->MoveTo(CPoint(0,300));
pDC->LineTo(CPoint(1000,300));
static int y=60;
//处理从100逐渐向下移动直到整幅位图完全显示出来为止的情况
//设置一裁剪区域,只能在其中绘图,当位图落入此区域时可见,
//其未落入的部分不可,故在整副位图下过的过程给用户用的感觉
//好像是从顶部一点点出现
if(y<=100)
{
pDC->IntersectClipRect(300,100,340,140);
pDC->BitBlt(300,y,40,40,&dcCompatible,0,0,SRCCOPY);
}
//处理位图落入底线的情况,此时,位图的下半部分应该渐隐
if(y+40>300)
{
pDC->BitBlt(300,y,40,300-y,&dcCompatible,0,0,SRCCOPY);
InvalidateRect(CRect(300,y-1,340,y));
}
//正常情况,擦除位图下落过程中遗留下的部分
else
{
pDC->BitBlt(300,y,40,40,&dcCompatible,0,0,SRCCOPY);
InvalidateRect(CRect(300,y-1,340,y));
}
//纵坐标自增
y++;
//重置y,使位图循环显示
if(y>340)
{
y=60;
}
CView::OnTimer(nIDEvent);
}
二、文字的平滑移动
利用裁剪区域实现文字的平滑移动:
步骤:
1、创建基于对话框的应用程序(MFC AppWizard),工程名为SmoothMoving;
2、的对话框的主界面上删除所有控件;
3、在CSmoothMovingView类中增加对WM_CREATE和WM_TIMER的消息处理。
4、在WM_CREATE的消息响应函数中设置一个定时器,具体代码如下:
int CSmoothMovingView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
SetTimer(1,10,NULL);
return 0;
}
5、在WM_TIMER的消息响应函数中增加如下代码:
void CTestDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//相关信息 48,100,432,116
InvalidateRect(CRect(48,100,432,116),TRUE);
CDialog::OnTimer(nIDEvent);
}
在WM_PAINT的消息响应函数中增加如下代码:结果如下所示:
void CTestDlg::OnPaint()
{
//****************我们添加的代码**********************
//字符串长度1648
//相关信息 48,100,432,116
static int X=432;
CString str,str1;
str.Format("在我几十年的人生岁月中,也曾有过生不逢时的迷茫,也曾感叹过外国的月亮比中国园。但那都已成为过去,如今我已经学会客观的看世界和用心去生活,我自认为比较的成熟了。成熟后经常想到的问题就是:作为一个中国人的自豪。");
CPaintDC dc(this);
dc.SetTextColor(RGB(255,0,0));
dc.SetBkMode(TRANSPARENT);
dc.IntersectClipRect(48,100,432,116);
dc.TextOut(X,100,str);
X--;
if(X<=-1000)
dc.TextOut(X+1600,100,str);
if(X<=-1600)
X=X+1880;
//***************添加的代码结束*********************
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}