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

本文详细介绍了Win32平台下使用双缓冲技术解决窗口绘画闪烁问题的方法。通过对比未使用双缓冲技术的代码与使用双缓冲技术的代码,展示了如何通过提前加载资源到内存并复制到设备DC来避免窗口闪烁。

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);	
		}

结果就是,窗口大小变化,就会闪烁如下图:
在这里插入图片描述
在这里插入图片描述
双缓冲技术:

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);
		
	}

结果如期望所想不会随着大小的变换二频繁闪烁。
在这里插入图片描述

总结:

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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发如雪-ty

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值