2007年3月28日 星期三

GDI+ how to?

Today, I will show all of you how to create a dialog or control which can using GDI+.

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(this); }

// 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

沒有留言: