在利用了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();
这种方法为由原来的窗口状态转为最大化,在显示窗口时会出现抖动。