内存DC

来源:百度文库 编辑:神马文学网 时间:2024/05/23 21:18:47

在使用VC开发图形相关的应用程序时,常常需要使用MFC的CDC类直接把图形画在窗口上。这通常是通过响应Windows的WM_PAINT消息实现的。如果要画的图形比较复杂,或者比较大,那么画图过程可能会造成窗口的闪烁。当窗口调整大小时,这种闪烁由为明显。

解决窗口闪烁问题的有效办法就是使用内存DC,也称为缓冲DC。在内存中准备一个和窗口DC相同属性的DC,在这个内存DC上执行画图操作。完成画图以后,把画图输出的内容整体复制到目标窗口DC上。因为画图操作不在窗口DC上进行,所以在画图的过程中窗口可以保持原来的内容。当画好的内容被复制到窗口DC时,因为复制操作执行的非常快,所以用户感觉窗口仿佛被立刻被画好,从而消除了从旧画面到白板再到新画面的闪烁现象。

生成内存DC主要用到以下四个函数:

CreateCompatibleDC(CDC* pDC )。CDC类的成员函数,用于创建一个和pDC指向的DC兼容的内存DC。

CreateCompatibleBitmap( CDC* pDC, int nWidth, int nHeight)。CBitmap类的成员函数,用于按指定尺寸创建一个和pDC指向的DC兼容的位图。     

SelectObject(CBitmap * pBitmap)。CDC类的成员函数,执行以后,所以在该DC上的图像输出都将被画到pBitmap指向的位图上。

BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop);CDC类的成员函数,用于从源DC(pSrcDC)复制一个矩形的图象到当前DC中。

  hdcDest:指向目标设备环境的句柄。

  nXDest:指定目标矩形区域左上角的X轴逻辑坐标。

  nYDest:指定目标矩形区域左上角的Y轴逻辑坐标。

  nWidth:指定源和目标矩形区域的逻辑宽度。

  nHeight:指定源和目标矩形区域的逻辑高度。

  hdcSrc:指向源设备环境的句柄。

  nXSrc:指定源矩形区域左上角的X轴逻辑坐标。

  nYSrc:指定源矩形区域左上角的Y轴逻辑坐标。

  dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。SRCCOPY:将源矩形区域直接拷贝到目标矩形区域。  过程: 1.以屏幕DC建立内存DC(CreateCompatibleDC)以屏幕DC建立位图(CreateCompatibleBitmap)  大小使用GetClientRect取得客户区大小    将上面创建的位图选入内存DC中(SelectObject) 2.所有的绘图动作都针对内存DC进行。 3.完成绘图动作后,将内存DC中内容复制到屏幕DC中。 4.释放资源。 注意点:
建立位图一定要使用屏幕DC
如果屏幕DC有使用调色板,则必须将此调色板选入内存DC中,否则将发生色彩不正确的情况。 例子:
         CDC memdc;

         CBitmap bitmap;

         CBitmap *pOldBitmap;

         CRect rect;

 

         GetClientRect(&rect);

         memdc.CreateCompatibleDC(pDC); //以屏幕DC 建立内存DC

         bitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//以屏幕DC建立位图

         pOldBitmap = memdc.SelectObject(&bitmap);//将上面创建的位图选入内存DC中,返回CBitmap的指针并赋给pOldBitmap

 

         //下面可以在memdc上进行绘图操作

         memdc.FillSolidRect(rect,RGB(0,0,0));

         CString str;

         str.Format("%d",212);

         memdc.SetBkColor(RGB(0,0,255));

         memdc.SetTextColor(RGB(255,0,0));

         memdc.TextOut(rect.left+rect.Width()/2,rect.top+10,str);

         //绘图结束

         pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memdc,0,0,SRCCOPY); // 从内存DC复制到屏幕DC

         memdc.SelectObject(pOldBitmap);