思想:
之所以闪屏,是因为鼠标在移动过程中,一直都在执行修补语句
pDC->BitBlt(rect.left,rect.top ,rect.Width(),rect.Height(),&DownmemDc,rect.left,rect.top,SRCCOPY);
(从在鼠标Down下去的时候保存的屏幕DC设备中截取相应大小的位图去填补在鼠标UP之前的鼠标移动过所产生的线段的痕迹,从而达到画橡皮线的效果)
双缓存是创建了两个内存设备,把贴图修补的工作留在了另一个内存设备中进行。修补完以后,才把图贴到屏幕上,从而解决闪屏的问题。
步骤1. 在头文件中创建 内存设备,起始点,终点
CDC DownmemDc;
CPoint m_PtDown;
CPoint m_PtEnd;
步骤2. 在BUTTONdown事件中添加代码:
m_PtDown = point;
m_PtEnd = point;
if ( DownmemDc) // 如果Up事件不在客户区发生,将导致程序崩溃,所以每次Down事件开始要做判断。
DownmemDc.DeleteDC();
CDC *pDc = GetDC();
CRect rect;
GetClientRect(&rect);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDc,rect.Width(),rect.Height());
DownmemDc.CreateCompatibleDC(pDc); // 内存设备1
DownmemDc.SelectObject(&bitmap);
DownmemDc.BitBlt(0,0,rect.Width(),rect.Height(),pDc,0,0,SRCCOPY);
ReleaseDC(pDc); // 释放DC设备
步骤3 . 在MOUSEMove事件 中添加代码:
CDC *pDc = GetDC();
if(nFlags & MK_LBUTTON)
{
CBrush brush; // 创建画刷
brush.CreateStockObject(NULL_BRUSH);
CRect rectScreen; // 创建与当前设备大小的相同的矩形
GetClientRect( &rectScreen);
CBitmap bitmap; // 创建与当前设备兼容的BITMAP位图
bitmap.CreateCompatibleBitmap(pDc,rectScreen.Width(),rectScreen.Height());
DownmemDc2.CreateCompatibleDC(pDc); // 创建与当前设备兼容的内存设备2
DownmemDc2.SelectObject( &bitmap);
// 修补位图
CRect rect(m_PtDown,m_PtEnd);
rect.NormalizeRect();
rect.InflateRect(3,3);
// 从第一个内存设备中截取相应大小的位图填补鼠标划过生成的线段,( 这个过程在另一个内存设备中进行)
DownmemDc2.BitBlt(0,0 ,rectScreen.Width(),rectScreen.Height(),&DownmemDc,0,0,SRCCOPY);
m_PtEnd = point;
CRect NewRect(m_PtDown,point);
// 在内存上画线 (双缓存画线)
DownmemDc2.SelectObject(&brush);
DownmemDc2.MoveTo(m_PtDown);
DownmemDc2.LineTo(point);
//
/// 把从内存设备中修补好的图贴到屏幕设备上
pDc->BitBlt(0,0,rectScreen.Width(),rectScreen.Height(),&DownmemDc2,0,0,SRCCOPY);
DownmemDc2.DeleteDC(); // 删除内存设备
bitmap.DeleteObject(); // 删除bitmap变量
ReleaseDC(pDc); // 释放pDc
如有错误,还请批评指正,共同学习!