亲们,小弟刚接触MFC,做了个小动画类的东西,我用了双缓冲和InvalidateRect了,但为什么还是闪烁呢
下面是OnDraw的代码:
void CMovingBallView::OnDraw(CDC* pDC)
{
CMovingBallDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//Draw background pic
CRect rect;
GetClientRect(&rect);
pDC-> StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memdc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
//get client size;
CRect cRect;
GetClientRect(&cRect);
CString temp;
//遍历存储CBall的vector;
CClientDC cdc(this);
CString add = _T(" SPACE to Stop,And Click to Add More.\n");
for(int i = 0;i< ballVec.size();i++){
ballVec[i].winH = cRect.bottom;
ballVec[i].winW = cRect.right;
temp.Format(_T("| BALL:(%d , %d) 碰撞次数: %ds |"),ballVec[i].m_Center.x,ballVec[i].m_Center.y,ballVec[i].m_CrashTimes);
add+=temp;
DrawTransBitmap( cdc.GetSafeHdc(),ballVec[i].m_Center.x,ballVec[i].m_Center.y,89,89, // 目标高度
memDC.GetSafeHdc(), 0, 0, ballVec[i].m_TransColor);
}
//Draw Info_text backgroud rect
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,cRect.right,30);
CDC memRectDC;
memRectDC.CreateCompatibleDC(pDC);
memRectDC.SelectObject(&bmp);
memRectDC.FillSolidRect(0,0,cRect.right,30,RGB(0x08,0x08,0x08)); //蓝色 1874CD
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0x40; //半透明,0为全透明
bf.AlphaFormat = 0;
AlphaBlend(pDC-> GetSafeHdc(),0,0,cRect.right,30,memRectDC.GetSafeHdc(),0,0,cRect.right,30,bf);
pDC->MoveTo(0,30);
pDC->LineTo(cRect.right,30);
//显示INFO
cdc.SetBkMode(TRANSPARENT);
cdc.DrawText(add,-1,CRect(0,0,cRect.right,30),DT_LEFT + DT_WORDBREAK + DT_END_ELLIPSIS);
}
其中兼容DC是在onCreate里创建的.谢谢大神帮助额
下面是OnDraw的代码:
void CMovingBallView::OnDraw(CDC* pDC)
{
CMovingBallDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//Draw background pic
CRect rect;
GetClientRect(&rect);
pDC-> StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memdc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
//get client size;
CRect cRect;
GetClientRect(&cRect);
CString temp;
//遍历存储CBall的vector;
CClientDC cdc(this);
CString add = _T(" SPACE to Stop,And Click to Add More.\n");
for(int i = 0;i< ballVec.size();i++){
ballVec[i].winH = cRect.bottom;
ballVec[i].winW = cRect.right;
temp.Format(_T("| BALL:(%d , %d) 碰撞次数: %ds |"),ballVec[i].m_Center.x,ballVec[i].m_Center.y,ballVec[i].m_CrashTimes);
add+=temp;
DrawTransBitmap( cdc.GetSafeHdc(),ballVec[i].m_Center.x,ballVec[i].m_Center.y,89,89, // 目标高度
memDC.GetSafeHdc(), 0, 0, ballVec[i].m_TransColor);
}
//Draw Info_text backgroud rect
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,cRect.right,30);
CDC memRectDC;
memRectDC.CreateCompatibleDC(pDC);
memRectDC.SelectObject(&bmp);
memRectDC.FillSolidRect(0,0,cRect.right,30,RGB(0x08,0x08,0x08)); //蓝色 1874CD
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0x40; //半透明,0为全透明
bf.AlphaFormat = 0;
AlphaBlend(pDC-> GetSafeHdc(),0,0,cRect.right,30,memRectDC.GetSafeHdc(),0,0,cRect.right,30,bf);
pDC->MoveTo(0,30);
pDC->LineTo(cRect.right,30);
//显示INFO
cdc.SetBkMode(TRANSPARENT);
cdc.DrawText(add,-1,CRect(0,0,cRect.right,30),DT_LEFT + DT_WORDBREAK + DT_END_ELLIPSIS);
}
其中兼容DC是在onCreate里创建的.谢谢大神帮助额
void CMovingBallView::OnDraw(CDC* pDC)
{
CMovingBallDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
//Draw background pic
CRect rect;
GetClientRect(&rect);
pDC-> StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memdc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
//get client size;
CRect cRect;
GetClientRect(&cRect);
CString temp;
//遍历存储CBall的vector;
CClientDC cdc(this);
CString add = _T(" SPACE to Stop,And Click to Add More.\n");
for(int i = 0;i< ballVec.size();i++){
ballVec[i].winH = cRect.bottom;
ballVec[i].winW = cRect.right;
temp.Format(_T("| BALL:(%d , %d) 碰撞次数: %ds |"),ballVec[i].m_Center.x,ballVec[i].m_Center.y,ballVec[i].m_CrashTimes);
add+=temp;
DrawTransBitmap( cdc.GetSafeHdc(),ballVec[i].m_Center.x,ballVec[i].m_Center.y,89,89, // 目标高度
memDC.GetSafeHdc(), 0, 0, ballVec[i].m_TransColor);
}
//Draw Info_text backgroud rect CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC,cRect.right,30);
CDC memRectDC;
memRectDC.CreateCompatibleDC(pDC);
memRectDC.SelectObject(&bmp);
memRectDC.FillSolidRect(0,0,cRect.right,30,RGB(0x08,0x08,0x08)); //蓝色 1874CD
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 0x40; //半透明,0为全透明
bf.AlphaFormat = 0;
AlphaBlend(pDC-> GetSafeHdc(),0,0,cRect.right,30,memRectDC.GetSafeHdc(),0,0,cRect.right,30,bf);
pDC->MoveTo(0,30);
pDC->LineTo(cRect.right,30);
//显示INFO
cdc.SetBkMode(TRANSPARENT);
cdc.DrawText(add,-1,CRect(0,0,cRect.right,30),DT_LEFT + DT_WORDBREAK + DT_END_ELLIPSIS);
}
pDC-> StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memdc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY); 不等于是在刷背景吗?你这哪是什么又缓冲啊!一般来说你做到在OnDraw里面只有一条bitblt语句,就是双缓冲。
如果你是显示一个动画,肯定不能在OnDraw里面做了,应该在需要完全重绘的时候才调用OnDraw,比如窗口最小化之后又恢复。正确的做法应该是在定时器里面,只对你运动的部分进行擦除与重绘。
保证一次性使用
pDC-> StretchBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memdc,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);所有工作在memdc中完成了再用上面一句话
谢谢,受教了,再请教您个问题:
我吧所有东西都在一个缓存memDC里面画,然后再显示到屏幕pDC上,然后我把存放背景的缓存memBkDC画在memDC这个统一的缓存DC上,但是在pDC->bitblt();后怎么显示不出背景呢?
是不是不可以吧缓存DC绘制到缓存DC再绘制到屏幕呢?
弄出来了,看了你的绘制不规则位图里发现我的少了这两句:
tempBitmap.CreateCompatibleBitmap(pDC,rect.right,rect.bottom);
memdc.SelectObject(&tempBitmap);
但还是不知道为什么要加这个啊.