17.7.3 利用双缓冲解决闪屏问题
首先需要创建一个内存设备缓冲图像,然后将图像绘制到内存设备上,最后将内存设备上的内容复制到屏幕上。
- 01 void CDialogGDIDlg::OnPaint()
- 02 {
- 03 CPaintDC dc(this); //设备描述符
- 04 CDC dcMemory;
- 05 dcMemory.CreateCompatibleDC(NULL); //创建设备兼容的内存设备
- 06 CRect bkRect;
- 07 GetClientRect(&bkRect); //获取客户区域大小区域
- 08 CBitmap bitmap;
- 09 bitmap.CreateCompatibleBitmap(&dc, bkRect.Width(), bkRect.
- Height());
- 10 SelectObject(dcMemory.GetSafeHdc(), bitmap); //将位图载入内存设备
- 11 using namespace Gdiplus;
- 12 Graphics graphics(dcMemory.m_hDC);
- 13 Pen newPen(Color(0,255,0),3);
- 14 //创建一个填充画刷,前景色为红色,背景色为蓝色
- 15 HatchBrush newBrush(HatchStyleCross,Color(255,255,0,0),Color
- (255,0,0,255));
- 16 //在(10,10)处绘制一个长为200,高为100的矩形
- 17 graphics.DrawRectangle(&newPen,10,10,200,100);
- 18 //在(10,10)处填充一个长为200,高为100的矩形区域
- 19 graphics.FillRectangle(&newBrush,10,10,200,100);
- 20 dc.BitBlt(0,0,bkRect.Width(),bkRect.Height(),&dcMemory,0,
- 0,SRCCOPY);
- 21 }
【代码解析】
第4、5行创建一个内存设备,并创建设备的兼容性。第6、7行获取窗体的大小。第8~10行根据窗体大小创建一个位图,并将这个位图选入内存设备。第11~19行利用GDI+将图像绘制到内存设备上。第20行利用GDI将内存图像复制到屏幕上。
最后还要重载窗体的OnEraseBkgnd()函数,避免窗体底色的干扰。
- 01 BOOL CDialogGDIDlg::OnEraseBkgnd(CDC* pDC)
- 02 {
- 03 return true; //去除窗体背景色干扰
- 04 }
此时即可避免因定时器的刷屏而引起的闪屏问题。