<2019年6月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

统计

  • 随笔 - 2
  • 文章 - 0
  • 评论 - 0
  • 引用 - 0

常用链接

留言簿

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜

2012年8月2日

利用CMemDC画图的两种方法

方法一: 在VS 2010中有一个类CMemDC, 在MFC下可解决绘图闪烁。

看看MSDN钟怎么说的:

CMemDC Class
A helper class for a memory device context. The memory device context supports offscreen drawing.
在库中的声明如下

使用方法: 
// 1、响应WM_ERASEBKGND消息,返回FALSE,这样就不擦除背景了。 
// 2、在需要作图的地方使用CMemDC。

二: 网上有另外一种利用CMemDC继承CDC的方式如下: 
使用方法类同前面所述: 








 


 

posted @ 2012-08-02 20:06 教主 阅读(475) | 评论 (0)编辑 收藏
CmemDC类 的使用方法

CMemDC其实就是对内存DC的创建与删除进行一个包装。
1、在CMemDC的构造函数中创建内存DC;
2、用户可以在CMemDC dc中进行图像的绘制;
3、在CMemDC的析构函数中进行内存DC到目标DC的拷贝,并做相应的GDI对象清理工作。

使用这样的类可以让你的代码有很大程度的简洁。

举个例子:
如果我们不使用CMemDC,一般我们会写下面的一段的代码,

CView::OnDraw(CDC* pDC)
{
  CRect rcClient;
  GetClientRect(&rcClient);
  CDC dcMem;
  dcMem.CreateCompatibleDC(pDC);
  CBitmap bmpMem;
  bmpMem.CreateCompatibleBitmap(pDC,rcClient.Width(),rcClient.Height());
  CBitmap *pBmpOld = dcMem.SelectObject(&bmpMem);

  //下面进行图像的绘制
  dcMem.DrawText();
  dcMem.FillSolidRect();

  pDC->BitBlt(rcClient.left,rcClient.top,rcClient.Width(),rcClient.Height(),
  &dcMem,0,0,SRCCOPY);

  //GDI对象的清理
  dcMem.SelectObject(pBmpOld);
  bmpMem.DeleteObject();
  dcMem.DeleteDC();
}
如果我们使用了CMemDC,那么代码就可以这样写,简洁了很多,更便于维护而且不容易出错。
CView::OnDraw(CDC* pDC)
{
  CMemDC dcMem(pDC);
  //下面进行图像的绘制
  dcMem.DrawText();
  dcMem.FillSolidRect();
}

一般不用自己写个类,不过有封装更好.
简单来说,步骤这样:(比如你真正的使用CDC *dc来绘制)
1.建立dc的内存DC
m_MemDc.CreateCompatibleDC(dc);
2.创建画布
m_bmp.CreateCompatibleBitmap(dc,宽度,高度);
3.选择画布
m_oldBmp = m_MemDc.SelectObject(&m_bmp);
4.内存Dc绘制东西
...
...
绘制自己需要的东西
5.使用真正绘图的dc拷贝内存dc的内容
dc.BitBlt(left,top,宽度,高度,&m_MemDc,m_MemDc中的起始X,m_MemDc中的起始y,SRCCOPY)
6.最后这个内存DC释放掉
m_MemDc.DeleteDC(); 

CMemDC类 其主要功能其实就是提供一个内存DC用于绘制,用于消除绘制时的闪烁,即双缓存机制。
一般来说,我们将将要显示的图首先绘制在内存DC上,然后在要显示的时候整个更新到前台DC上(使用BitBlt)。

我们首先来看一下CMemDC类的数据成员
private:  
  CBitmap  m_bitmap;  // Offscreen bitmap
  CBitmap*  m_oldBitmap;  // bitmap originally found in CMemDC
  CDC*    m_pDC;  // Saves CDC passed in constructor
  CRect    m_rect;  // Rectangle of drawing area.
  BOOL    m_bMemDC;  // TRUE if CDC really is a Memory DC.
可以看到这当中有两个重要的元素:m_bitmap和m_pDC。打个也许不大恰当的比方,
m_pDC指向的CDC对象好比是一张画板,我们将画画在上面,画好的画就是m_bitmap。
当我们将内存DC用BitBlt到前台DC的时候,正好就是将刚刚画的画显示到前台。



posted @ 2012-08-02 10:57 教主 阅读(3567) | 评论 (0)编辑 收藏
仅列出标题