解决绘图闪烁问题--双缓冲技术

一、缓冲技术原理:为了解决窗口刷新频率过快所带来的闪烁问题,利用双缓冲技术进行绘图。所谓双缓冲技术,就是将资源加载到内存,然后复制内存数据到设备DC(这个比较快),避免了直接在设备DC上绘图(这个比较慢)。

二、列子示例:

  1 void CDlgDrawSignature::OnPaint()
  2 {
  3     CPaintDC dc(this); // device context for painting
  4     // TODO: 在此处添加消息处理程序代码
  5     // 不为绘图消息调用 CDialogEx::OnPaint()
  6 
  7     CRect ctrlRect;
  8     this->GetClientRect(&ctrlRect);//获取尺寸
  9 
 10     
 11     CDC dcMemory;
 12     dcMemory.CreateCompatibleDC(&dc);//创建内存DC
 13 
 14 
 15     CBitmap *pOldMapMemory;
 16     CBitmap mapMemory;
 17     mapMemory.CreateCompatibleBitmap(&dc, ctrlRect.Width(), ctrlRect.Height());//创建控件DC的兼容位图。其实就是与控件DC大小相同的一块区域
 18     pOldMapMemory = dcMemory.SelectObject(&mapMemory);//加载兼容位图,只有制定了“桌布”尺寸之后,你才能在内存DC上面绘图
 19 
 20     dcMemory.FillRect(&ctrlRect,&CBrush(RGB(255,255,255)));    
 21     DrawButton(&dcMemory);//在内存DC上绘图
 22 
 23     dc.BitBlt(0, 0, ctrlRect.Width(), ctrlRect.Height(), &dcMemory, 0, 0, SRCCOPY);//将内存DC上的内容复制到控件DC上
 24     dcMemory.SelectObject(pOldMapMemory);//还原原来的内存DC
 25     ::DeleteObject(mapMemory);//删除兼容位图资源
 26     ::DeleteDC(dcMemory);//删除内存DC
 27     ReleaseDC(&dc);//释放控件DC
 28 }
 29 
 30 void CDlgDrawSignature::DrawButton(CDC* pDc)
 31 {
 32     //画黑色标题栏
 33     CBrush brush(RGB(0,0,0));
 34     pDc->FillRect(&m_rcHit,&brush);
 35 
 36     CPoint   point;
 37     GetCursorPos(&point);
 38     ScreenToClient(&point);
 39     if (m_rcClose.PtInRect(point))
 40     {
 41         //红色关闭按钮背景
 42         CBrush brushRed(RGB(255,0,0));
 43         pDc->FillRect(&m_rcClose,&brushRed);
 44     }
 45 
 46     //画白色关闭的X
 47     CPen pen(PS_SOLID,2,RGB(255,255,255));
 48     CPen* penOld = pDc->SelectObject(&pen);
 49     pDc->MoveTo(CPoint(m_rcClose.left+4,m_rcClose.top+4));
 50     pDc->LineTo(CPoint(m_rcClose.right-4,m_rcClose.bottom-4));
 51     pDc->MoveTo(CPoint(m_rcClose.right-4,m_rcClose.top+4));
 52     pDc->LineTo(CPoint(m_rcClose.left+4,m_rcClose.bottom-4));
 53     pDc->SelectObject(penOld);
 54 
 55     //绘画保存按钮
 56     CPen penBorder(PS_SOLID,1,RGB(0,0,0));
 57     penOld = pDc->SelectObject(&penBorder);
 58     pDc->Rectangle(&m_rcSave);
 59     pDc->SelectObject(penOld);
 60     if (m_rcSave.PtInRect(point))
 61     {
 62         CBrush brushBlue(RGB(65,105,255));
 63         pDc->FillRect(&m_rcSave,&brushBlue);
 64         m_bSave = TRUE;
 65     }
 66     else
 67     {
 68         m_bSave = FALSE;
 69     }
 70     //设置字体  
 71     CFont font;  
 72     font.CreateFont( 18,                    //   nHeight     
 73         0,                                  //   nWidth     
 74         0,                                  //   nEscapement   
 75         0,                                  //   nOrientation     
 76         FW_NORMAL,                          //   nWeight     
 77         FALSE,                              //   bItalic     
 78         FALSE,                              //   bUnderline     
 79         0,                                  //   cStrikeOut     
 80         ANSI_CHARSET,                       //   nCharSet     
 81         OUT_DEFAULT_PRECIS,                 //   nOutPrecision     
 82         CLIP_DEFAULT_PRECIS,                //   nClipPrecision     
 83         DEFAULT_QUALITY,                    //   nQuality     
 84         DEFAULT_PITCH   |   FF_SWISS,       //   nPitchAndFamily       
 85         _T("宋体"));  
 86 
 87     CFont* pFont = pDc->SelectObject(&font);  
 88     pDc->SetBkMode(TRANSPARENT);
 89     pDc->DrawText("保  存",&m_rcSave,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
 90 
 91 
 92     //绘画清除按钮
 93     penOld = pDc->SelectObject(&penBorder);
 94     pDc->Rectangle(&m_rcClear);
 95     pDc->SelectObject(penOld);
 96     if (m_rcClear.PtInRect(point))
 97     {
 98         CBrush brushBlue1(RGB(65,105,255));
 99         pDc->FillRect(&m_rcClear,&brushBlue1);
100         m_bClear = TRUE;
101     }
102     else
103     {
104         m_bClear = FALSE;
105     }
106 
107     pDc->DrawText("清  除",&m_rcClear,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
108 
109     pDc->SelectObject(pFont);
110 }

 

posted @ 2017-12-18 14:26  风的哀伤  阅读(650)  评论(0编辑  收藏  举报