MFC双缓冲简介
一、MFC为什么要实现双缓冲
在MFC界面绘图中,时常会遇到界面闪烁问题,尤其是在绘图不断更新的过程中,原因是“旧”图像还没擦除,“新”图像已经绘制,附加显示器刷新率及肉眼等问题,造成图像闪烁,给用户体验降低;在该条件下,需要通过双缓冲机制进行,关于闪烁的具体解释可参考https://en.wikipedia.org/wiki/Multiple_buffering。下面是MFC在没有双缓冲条件下的代码效果:
1、启动计时器
1 SetTimer(1, 50, NULL);
2、计时器事件处理
1 void CMFCPaintingDlg::OnTimer(UINT_PTR nIDEvent) 2 { 3 Invalidate(); 4 CDialogEx::OnTimer(nIDEvent); 5 }
3、窗体WM_PAINT事件
static int value = 0; void CMFCPaintingDlg::OnPaint() { CPaintDC dc(this); Graphics graphics(dc); graphics.SetSmoothingMode(SmoothingModeHighQuality); value += 5; DrawTJGraph(graphics, value); CDialogEx::OnPaint(); }
4、功能函数实现
void CMFCPaintingDlg::DrawTJGraph(Graphics & graphics, int rotateValue) { CRect rect; CPoint pt; int r=200; GetClientRect(&rect); graphics.TranslateTransform(rect.Width()/2, rect.Height()/2); graphics.RotateTransform(rotateValue); graphics.FillPie(&SolidBrush(Color(255, 255, 255)), -r / 2, -r / 2, r, r, 90, 180); graphics.FillPie(&SolidBrush(Color(0, 0, 0)), -r / 2, -r / 2, r, r, -90, 180); graphics.FillEllipse(&SolidBrush(Color(255, 255, 255)), -r / 4, -r / 2, r / 2, r / 2); graphics.FillEllipse(&SolidBrush(Color(0, 0, 0)), -r / 4, 0, r / 2, r / 2); graphics.FillEllipse(&SolidBrush(Color(0, 0, 0)), -r / 8, -3 * r / 8, r / 4, r / 4); graphics.FillEllipse(&SolidBrush(Color(255, 255, 255)), -r / 8, r / 8, r / 4, r / 4); }
二、MFC中实现双缓冲绘图
代码效果如下所示:
1、变量定义
CDC MemDCIndicator;
CBitmap MemBitmapIndicator;
CDC *pDC;
2、启动定时器
1 SetTimer(1, 50, NULL);
3、定时器时间处理
1 static int value = 0; 2 void DoubleBufferDlg::OnTimer(UINT_PTR nIDEvent) 3 { 4 value += 5; 5 CRect rt; 6 GetClientRect(&rt); 7 pDC = GetDC(); 8 //创建内存中的显示设备 9 MemDCIndicator.CreateCompatibleDC(pDC); 10 //创建内存中的图像 11 MemBitmapIndicator.CreateCompatibleBitmap(pDC, rt.Width(), rt.Height()); 12 //指定内存显示设备在内存图像上画图 13 MemDCIndicator.SelectObject(&MemBitmapIndicator); 14 //初始化绘图背景 15 MemDCIndicator.FillSolidRect(rt, RGB(100, 100, 100)); 16 //功能函数 17 DrawTJGraph(MemDCIndicator, value); 18 //将内存中图像呈现 19 pDC->BitBlt(rt.left, rt.top, rt.Width(), rt.Height(), &MemDCIndicator, 0, 0, SRCCOPY); 20 //释放资源 21 MemDCIndicator.DeleteDC(); 22 MemBitmapIndicator.DeleteObject(); 23 ReleaseDC(pDC); 24 CDialogEx::OnTimer(nIDEvent); 25 }
4、功能函数
1 void DoubleBufferDlg::DrawTJGraph(CDC & dc, int rotateValue) 2 { 3 Graphics graphics(dc); 4 graphics.SetSmoothingMode(SmoothingModeHighQuality); 5 CRect rect; 6 int r = 200; 7 GetClientRect(&rect); 8 graphics.TranslateTransform(rect.Width() / 2, rect.Height() / 2); 9 graphics.RotateTransform(rotateValue); 10 11 graphics.FillPie(&SolidBrush(Color(255, 255, 255)), -r / 2, -r / 2, r, r, 90, 180); 12 graphics.FillPie(&SolidBrush(Color(0, 0, 0)), -r / 2, -r / 2, r, r, -90, 180); 13 14 graphics.FillEllipse(&SolidBrush(Color(255, 255, 255)), -r / 4, -r / 2, r / 2, r / 2); 15 graphics.FillEllipse(&SolidBrush(Color(0, 0, 0)), -r / 4, 0, r / 2, r / 2); 16 17 graphics.FillEllipse(&SolidBrush(Color(0, 0, 0)), -r / 8, -3 * r / 8, r / 4, r / 4); 18 graphics.FillEllipse(&SolidBrush(Color(255, 255, 255)), -r / 8, r / 8, r / 4, r / 4); 19 }
又没有什么可说的
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步