win32-双缓冲-解决窗口移动拉伸闪烁问题

win32-双缓冲

这个技术主要是用来解决窗口闪烁问题的,本人亲测在单一画面有效果。其实造成闪烁的原因是因为窗口绘画需要时间,所以我们看着就像是在闪烁。其实实现原理主要就是提前把资源加载到内存,然后再将这个已经加载好的资源复制到设备DC。
看部分代码(没有使用双缓冲技术):

if (msg==WM_PAINT)
	{
     
		PAINTSTRUCT ps;
		
		HBRUSH hbrush, hbrushold;

		hbrush = CreateSolidBrush(RGB(255, 255, 0));

		HDC hdc = BeginPaint(hWnd, &ps);
		hbrushold = (HBRUSH)SelectObject(hdc, hbrush);

		MoveToEx(hdc, 100, 100, NULL);
		LineTo(hdc, 150, 230);
		Rectangle(hdc, 200, 200, 300, 300);
		Ellipse(hdc, 15, 15, 130, 130);

		SelectObject(hdc, hbrushold);

		DeleteObject(hbrush);
		
		EndPaint(hWnd, &ps);	
		}

结果就是,窗口大小变化,就会闪烁如下图:
win32-双缓冲-解决窗口移动拉伸闪烁问题_第1张图片
win32-双缓冲-解决窗口移动拉伸闪烁问题_第2张图片
双缓冲技术:

if (msg==WM_PAINT)
	{
     
		PAINTSTRUCT     ps;
		RECT rtClient;
		GetClientRect(hWnd, &rtClient);
		HDC hdc = BeginPaint(hWnd, &ps);
		HDC hMemDC = CreateCompatibleDC(hdc);
		HBITMAP hBitmap = CreateCompatibleBitmap(hdc, rtClient.right - rtClient.left, rtClient.bottom - rtClient.top);//rt为RECT变量;
		SelectObject(hMemDC, hBitmap);

		HBRUSH hbrush, hbrushold;

		hbrush = CreateSolidBrush(RGB(255, 0, 0));		
		hbrushold = (HBRUSH)SelectObject(hMemDC, hbrush);

		MoveToEx(hMemDC, 100, 100, NULL);
		LineTo(hMemDC, 150, 230);
		Rectangle(hMemDC, 200, 200, 300, 300);
		Ellipse(hMemDC, 15, 15, 130, 130);

		SelectObject(hMemDC, hbrushold);

		DeleteObject(hbrush);
		

		//FillRect(hMemDC, &rtClient, WHITE_BRUSH);


		BitBlt(hdc, 0, 0, rtClient.right - rtClient.left, rtClient.bottom - rtClient.top,
			hMemDC, 0, 0, SRCCOPY);
		DeleteDC(hMemDC);
		DeleteObject(hBitmap);
		EndPaint(hWnd, &ps);
		
	}

结果如期望所想不会随着大小的变换二频繁闪烁。
win32-双缓冲-解决窗口移动拉伸闪烁问题_第3张图片

总结:

1、声明
    HDC hMemDC;
   HBITMAP hBitmap;
2、创建相容的内存DC
hMemDC = CreateCompatibleDC(hdc);
3、创建位图
hBitmap = CreateCompatibleBitmap(hdc, rt.right - rt.left, rt.bottom - rt.top);//rt为RECT变量
4、将位图选入到内存DC中,没有这一步的话,内存DC只能是单色的,置换后才是多彩的
   SelectObject(hMemDC, hBitmap);
5、绘制
     …
6、拷贝到原先内存
BitBlt(hdc, 0, 0, rt.right - rt.left, rt.bottom - rt.top, hMemDC, 0, 0, SRCCOPY)

   7、释放内存
      DeleteDC(hMemDC);
      DeleteObject(hBitmap);

你可能感兴趣的:(win32,c++)