利用双缓冲技术使图像不在因刷新而不存在

本文介绍了解决MFC单文档应用中图形因刷新而消失的问题,通过采用双缓冲技术,确保图形在窗口最大化、最小化等操作时保持稳定显示。文章详细解释了双缓冲的原理,并提供了具体实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


             

    在利用了MFC的单文档来制作简单的图形时,遇到了这样的问题,在选择了右上角的最大化,最小化,还原时,图像便会因为刷新而消失,那么如果误操作,以前画的图像就很可能白费了功夫,为了解决这个问题,本人采用了双缓冲的技术,双缓冲,顾名思义,就是设有两个缓冲区,由于在未设置缓冲区之前,MFC绘图就仅使用一个设备描述表,由GDI 自动的将设备描述表的图像拷贝到显存来显示。而双缓冲区就是在有了设备描述表的前提下,手动建立与设备描述表相兼容的后备缓冲区,绘图过程中,首先将图形绘制在后备缓冲区中,然后在手动的将后备缓冲区中的图像拷贝到前端缓冲区中,再由GDI自动将前端缓冲区中的图像拷贝到显存完成图形的显示过程。两者之间的差别便是双缓冲多了一步将图像由后备缓冲区拷贝到设备描述表。

建立与设备描述表相兼容的后备缓冲区的步骤如下:

1.先设置与窗口设备描述表相兼容的内存设备描述表

2.设置与内存设备描述表相兼容的位图并将该位图选入内存设备描述表

3.在内存设备表上开始绘制

4.将内存设备表的内容拷贝到窗口设备描述表

 

因为图片刷新时会自动调用OnDraw() 函数,所以最后的拷贝显示要在OnDraw() 函数中来实现。首先创建一个全局变量,作为内存设备描述表,这样做的目的是可以在窗口中绘画多种形状而不会每次绘画后前面的全部消失,仅留下刚刚创建的图形。本人创建的如下:

CDC m_memdc;//创建的全局变量作为内存设备描述表 

//在OnDraw()函数中来创建该后备缓冲区

CRect rect;

GetClientRect(&rect);

 

If(!m_memdc)

{

CBitma   bitmap;

bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());

m_memdc.CreateCompatibleDC(NULL);

CBitmap *pOldbit = m_memdc.SelectObject(&bitmap);

m_memdc.FillSolidRect(0,0,rect.Width(),rect.Height(),RGB(255,255,255));

    }

    pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_memdc,0,0,SRCCOPY);

 

这样就建立好了后备缓冲区,以后的操作仅需要使用后备缓冲区来绘制,然后手动的转到窗口缓冲区便可以实现了。

另外,也是本人比较自豪的一件事,就是在最小化转到最大化的过程中,总会出现只能利用最小化之前的部分,超出的部分虽然显示了但并不能利用,为此我自己找到了一个函数,可以通过刷新来解决这个问题。因为再刷新的过程中OnDraw()函数同时会进行刷新,但其他的方法并不能被调用.那么个人想出了比较笨拙的方法,便是将窗口默认显示为最大,那么上述问题就不会出现了,绘制起来也比较的人性化。代码比较简单,但是在转化的过程中会有微小的抖动。就是在我个人的DrawSDIApp中的InitInstance中有显示窗口的命令,将其中的m_pMainWnd->ShowWindow(SW_SHOW);

  m_pMainWnd->UpdateWindow();

改为:

m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

m_pMainWnd->UpdateWindow();


这种方法为由原来的窗口状态转为最大化,在显示窗口时会出现抖动。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值