3、如何实现双缓冲 首先给出实现的程序,然后再解释,同样是在OnDraw(CDC *pDC)中:
CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象
//随后建立与屏幕显示兼容的内存显示设备 MemDC.CreateCompatibleDC(NULL); //这时还不能绘图,因为没有地方画 //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小 MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
//将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
//先用背景色将位图清除干净,这里我用的是白色作为背景 //你也可以用自己应该用的颜色 MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));
//绘图 MemDC.MoveTo(……); MemDC.LineTo(……);
//将内存中的图拷贝到屏幕上进行显示 pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
//绘图完成后的清理 MemBitmap.DeleteObject(); MemDC.DeleteDC(); 请参阅注释。
4、如何提高绘图的效率 实际上,在OnDraw(CDC *pDC)中绘制的图并不是所有都显示了的,例如:你在OnDraw中画了两个矩形,在一次重绘中虽然两个矩形的绘制函数都有执行,但是很有可能只有一个显示了,这是因为MFC本身为了提高重绘的效率设置了裁剪区。裁剪区的作用就是:只有在这个区内的绘图过程才会真正有效,在区外的是无效的,即使在区外执行了绘图函数也是不会显示的。因为多数情况下窗口重绘的产生大多是因为窗口部分被遮挡或者窗口有滚动发生,改变的区域并不是整个图形而只有一小部分,这一部分需要改变的就是pDC中的裁剪区了。因为显示(往内存或者显存都叫显示)比绘图过程的计算要费时得多,有了裁剪区后显示的就只是应该显示的部分,大大提高了显示效率。但是这个裁剪区是MFC设置的,它已经为我们提高了显示效率,在进行复杂图形的绘制时如何进一步提高效率呢?那就只有去掉在裁剪区外的绘图过程了。可以先用pDC->GetClipBox()得到裁剪区,然后在绘图时判断你的图形是否在这个区内,如果在就画,不在就不画。 如果你的绘图过程不复杂,这样做可能对你的绘图效率不会有提高。
具体程序大家可看以下源代码: 5、无闪烁背景图的绘制代码实现
/////////////// 无闪烁背景图绘制 ////////// //// 程序设计: icemen (温冰) 树爱兵 ////////////////////////////////////////////// BOOL CStrucView::OnEraseBkgnd(CDC* pDC) { int nWidth; int nHeight;
//CView::OnEraseBkgnd(pDC); CStrucDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CRect rect; GetWindowRect(&rect); nWidth = rect.Width(); nHeight= rect.Height();
CDC MemDC; CBitmap MemBitmap;
MemDC.CreateCompatibleDC (NULL); MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight);
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(255,255,255));
/////////////////////////////////////////////////////// //// 以上为画背景色 ////////////// //// 以下为画背景图 ////////////// /////////////////////////////////////////////////////// GetClientRect(rect); BITMAP bm; CDC dcMem; VERIFY(m_bmp.GetObject(sizeof(bm),(LPVOID)&bm)); dcMem.CreateCompatibleDC(pDC); CBitmap *pOldBMP =( CBitmap *)dcMem.SelectObject(&m_bmp); MemDC.BitBlt( (rect.right - bm.bmWidth)/2, (rect.bottom - bm.bmHeight)/2, bm.bmWidth,bm.bmHeight,&dcMem,0,0,SRCCOPY); dcMem.SelectObject(pOldBMP); /////////////////////////////////////////////////////// //// 以上为画背景图 ////////////// ///////////////////////////////////////////////////////
pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY);
MemBitmap.DeleteObject(); MemDC.DeleteDC();
return TRUE; } /////////////// 无闪烁背景图绘制 ////////// /////////////////////////////////////////////
注:程序中m_bmp 为相应 的 StrucView.h中定义,为位图资源类
protected: CBitmap m_bmp; 并应加上下面段,当然,你可在任何时候加入loadBitmap 子例程,也可加入文件资源,那由得你了!
CStrucView::CStrucView() { VERIFY(m_bmp.LoadBitmap(IDB_BITMAP3)); }
|