CMemDC双缓冲绘图

之前的文章,我提到了GDI双缓冲绘图,代码比较复杂,或许应用的时候有点麻烦,所以这里推荐一个CMemDC类;

注意:在VC2010中,已经有CMemDC类了,所以我添加了命名空间;






// MemDC.h : header file
//


#ifndef MEMDC_H
#define MEMDC_H


//
// CMemDC - memory DC
//
// Author: Keith Rule
// Email:  keithr@europa.com
// Copyright 1996-1997, Keith Rule
//
// You may freely use or modify this code provided this
// Copyright is included in all derived versions.
//
// History - 10/3/97 Fixed scrolling bug.
//                   Added print support.
//           25 feb 98 - fixed minor assertion bug
//
// This class implements a memory Device Context


namespace MyMemDC
{
class CMemDC : public CDC
{
public:


// constructor sets up the memory DC
CMemDC(CDC* pDC) : CDC()
{
ASSERT(pDC != NULL);


m_pDC = pDC;
m_pOldBitmap = NULL;
m_bMemDC = !pDC->IsPrinting();


if (m_bMemDC)    // Create a Memory DC
{
pDC->GetClipBox(&m_rect);
CreateCompatibleDC(pDC);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_pOldBitmap = SelectObject(&m_bitmap);
SetWindowOrg(m_rect.left, m_rect.top);
}
else        // Make a copy of the relevent parts of the current DC for printing
{
m_bPrinting = pDC->m_bPrinting;
m_hDC       = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
}
}


// Destructor copies the contents of the mem DC to the original DC
~CMemDC()
{
if (m_bMemDC) 
{    
// Copy the offscreen bitmap onto the screen.
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
this, m_rect.left, m_rect.top, SRCCOPY);


//Swap back the original bitmap.
SelectObject(m_pOldBitmap);
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
}


// Allow usage as a pointer
CMemDC* operator->() {return this;}


// Allow usage as a pointer
operator CMemDC*() {return this;}


private:
CBitmap  m_bitmap;      // Offscreen bitmap
CBitmap* m_pOldBitmap;  // 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.
};
}






/


//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.


#endif //MEMDC_H


简单说明:

1:

CMemDC关联的是一个DC,一般是我们的对话框DC,可以通CClient获取; 会在内存创建一个和指定DC一样大小的内存DC;


然后可以在CMemDC对象上直接绘图,可以通过GDI或者GDI+的方式,一般可以用GDI+的方式绘图;


在CMemDC析构的时候就将图像绘制到对话框上了;


2:

如果CMemDC是长期存在的,为了提高效率,可以将CMemDC作为全局或者成员变量等,然后在CMemDC中添加一个绘图函数,就是析构中的代码;

这个可以自行添加;





简单应用:


#include <gdiplus.h>
using namespace Gdiplus;

#include "MemDC.h"

void Ctmfc1Dlg::OnBtnDrawImage()
{
// TODO: 在此添加控件通知处理程序代码


GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR           gdiplusToken;
 
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);


CClientDC dc(this);
MyMemDC::CMemDC memdc1(&dc);


Graphics g(memdc1->m_hDC);
g.Clear( Gdiplus::Color::White );


//GDI绘图
memdc1->MoveTo(0,0);
memdc1->LineTo(1000,1000);


 
//GDI+绘图
  Gdiplus::Bitmap bmp(L"t.bmp");
  g.DrawImage( &bmp, 0,0 ); 


}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值