For this case, it really quite simple.
Here I have to provide a simple template class which can be the base class of your
GDI+ dialog or window.
Header file is display below:
GdiPlusHelper.h
===========================================================
#ifndef __GDIPLUS_H__
#include
#endif
#pragma once
// link with the library
#pragma comment(lib, "GdiPlus")
using namespace Gdiplus;
template
class CGdiPlusHelper{
public:
CachedBitmap* cached_bitmap_;
// cached offscreen bitmap into which all the drawing goes
Graphics* mem_graphics_;
// memory graphics
Bitmap* mem_bitmap_;
ULONG_PTR gdiplus_token_;
RECT m_rcClient;
T* m_pT;
CGdiPlusHelper() : cached_bitmap_(NULL),
mem_bitmap_(NULL),
mem_graphics_(NULL)
{ m_pT = static_cast
// call this puppy to invalidate your window!
void SetDirty()
{
if(this->mem_graphics_)
{
delete mem_graphics_;
mem_graphics_ = NULL;
}
if(this->mem_bitmap_)
{
delete mem_bitmap_;
mem_bitmap_ = NULL;
}
if(this->cached_bitmap_)
{
delete cached_bitmap_;
cached_bitmap_ = NULL;
}
}
protected:
int ReSize(/*BOOL& bool_handled*/)
{
//bool_handled = FALSE;
m_pT->GetClientRect(&m_rcClient);
SetDirty();
return 0;
}
int Paint(/*BOOL& bool_handled*/)
{
CPaintDC pdc(m_pT/*->m_hWnd*/);
Graphics graphics(pdc.m_hDC);
ReSize();
int int_width = m_rcClient.right - m_rcClient.left;
int int_height = m_rcClient.bottom - m_rcClient.top;
if((int_width <= 0) (int_height <= 0)) return 0; // nothing to do here.... if(bool_double_buffering) { if(!mem_bitmap_) CreateOffScreenGraphics(int_width, int_height, &graphics); // draw from cached bitmap to window if(graphics.DrawCachedBitmap(cached_bitmap_, 0, 0) != Ok) { // make the bitmap again (display parameters changed) SetDirty(); CreateOffScreenGraphics(int_width, int_height, &graphics); graphics.DrawCachedBitmap(cached_bitmap_, 0, 0); } } else this->m_pT->Draw(&graphics, int_width, int_height);
return 0;
}
int CreateGDIPlus(/*BOOL& bool_handled*/)
{
// init GDI+
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&gdiplus_token_, &gdiplusStartupInput, NULL);
//bool_handled = FALSE;
return 0;
}
int DestroyGDIPlus(/*BOOL& bool_handled*/)
{
// get rid of all the gdi+ data
if(cached_bitmap_)
{
delete cached_bitmap_;
cached_bitmap_ = NULL;
}
if(this->mem_bitmap_)
{
delete mem_bitmap_;
mem_bitmap_ = NULL;
}
if(this->mem_graphics_)
{
delete mem_graphics_;
mem_graphics_ = NULL;
}
// and shutdown gdi+
Gdiplus::GdiplusShutdown(gdiplus_token_);
//bool_handled = FALSE;
return 0;
}
void CreateOffScreenGraphics(int int_width, int int_height, Graphics* pGraphics)
{
if(!int_width !int_height)
return; //don't have anything to do.
// create off-screen bitmap
mem_bitmap_ = new Bitmap(int_width, int_height);
// create off-screen graphics
mem_graphics_ = Graphics::FromImage(mem_bitmap_);
// draw to offscreen graphics
m_pT->Draw(mem_graphics_, int_width, int_height);
// now create the cached bitmap
cached_bitmap_ = new CachedBitmap(mem_bitmap_, pGraphics);
}
};
================================================================
T , can be your Dialog or control,
For example:
#include "GdiPlusHelper.h"
class CTestDialog: public CDialog, public CGdiPlusHelper
{
......
void Draw(Graphics* pGraphics, int nWidth, int nHeight);
};
or
class CTestCtrl: public CWnd, public CGdiPlusHelper
{
DECLARE_DYNAMIC(CTestCtrl)
......
void Draw(Graphics* pGraphics, int nWidth, int nHeight);
};
Is it simple?
Cheers,
Andrew
沒有留言:
張貼留言