内存cdc双缓冲问题

来源:互联网 发布:淘宝客服的技巧 编辑:程序博客网 时间:2024/06/07 21:05
 

在没有MSDN恶劣环境下,经过不断地摸索,我终于搞清楚了内存DC双缓冲显示不出来的问题!其实无论画图代码放在哪里,只要代码正确,肯定是能成功显示出来的,内存DC双缓冲并不要求画图代码非得放在一个什么特定的位置。

之前我的工程之所以显示不出东西,简单说来其原因在于DC内部坐标映射的问题,网上内存DC双缓冲并没有说明白这一点。

一下是一个典型的内存DC双缓冲例子,转自:http://hi.baidu.com/f234f234/blog/item/a17f4f0863710c950a7b8291.html

CRect rect;
this->GetClientRect(rect);
CBitmap bmpFace;
bmpFace.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());(1)注意把握rect的尺寸为客户区域大小;
之后将这幅画选入内存DC中,
CBitmap* pOldBmp = NULL;
pOldBmp = MemDC.SelectObject(&bmpFace);; (2)
之后可以开始在内存DC中进行任何绘制动作;
CBrush brush(RGB(255,255,255));
MemDC.FillRect(rect,&brush);
for(int i=0;i<500;i++)
{
MemDC.MoveTo(22+i,22);
MemDC.LineTo(22+i,277);
}
绘制完后将内存DC中的这幅图绘制到屏幕DC中来,
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,rect.left,rect.top,SRCCOPY); (3)
最后进行相关的资源回收动作,
MemDC.SelectObject(pOldBmp);
bmpFace.DeleteObject();。

上述代码至少有三处需要注意的地方,我已经标上了序号。其中(1)创建了一个与显示DC相兼容的位图,参数2,3指明了位图的大小,(2)处将这个位图选入了内存DC中,默认位图的左上角与内存DC的(0,0)处相对应,这一步的作用是让内存DC “有地方用来作画”。经过接下来的一番涂抹之后,在第(3)步把内存DC中的内容复制到显示DC中,前4个参数指明了目的DC(也就是显示DC)的区域坐标和大小,即我们想把内存DC中的内容复制到显示DC的什么位置,第5个参数指明了源DC(也就是内存DC),第6,7个参数指明了源DC的起始坐标,即我们想对内存DC中从什么地方开始的内容进行复制。

上述的例子中的矩形rect选用的是整个窗口客户区的矩形,所以下面的那些坐标都用的是这个矩形的坐标,这样就掩盖了坐标映射的问题。但是在我的工程中并不是对整个窗口客户区进行双缓冲绘图,而是对窗口中的一个小矩形,于是我改变了rect的位置和大小,但其它的代码都没动,因此就显示不出东西了。事实上,所有的绘图工作都顺利地进行了,只是都画在了我们看不到的地方。

如果双缓冲的区域不是整个客户区的话,我建议这样做:在内存DC的(0,0)起始点作图,画完之后把内存DC中的内容复制到显示DC的所需的位置;而不是在内存DC中的相应位置作图,然后在复制到显示DC所需位置,因为这样做的话需要在绘图时在内存DC中做太多的坐标变换,太麻烦。

另外,还发现一点就是在画折线的时候最好使用CDC::Polyline(……)函数,它比连续调用MoveTo()和LineTo()速度要快得多!

最好贴个图,我用内存DC解决了之前的离散的点的问题,先画折线,再画特殊的点。

原创粉丝点击