Click here to Skip to main content
15,895,746 members
Articles / Desktop Programming / MFC

Double Buffering With GDI+

Rate me:
Please Sign up or sign in to vote.
4.85/5 (23 votes)
11 Feb 20022 min read 241.1K   4.7K   92  
Simple example about Double Buffering with GDI+
// GDIPlusView.cpp : implementation of the CGDIPlusView class
//

#include "stdafx.h"
#include "GDIPlus.h"
#include"Mainfrm.h"
#include "GDIPlusDoc.h"
#include "GDIPlusView.h"
	using namespace Gdiplus;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CGDIPlusView

IMPLEMENT_DYNCREATE(CGDIPlusView, CView)

BEGIN_MESSAGE_MAP(CGDIPlusView, CView)
	ON_WM_CREATE()
	ON_WM_PAINT()
ON_COMMAND(ID_GRAPHICS_IMAGE, OnGraphicsImage)
ON_UPDATE_COMMAND_UI(ID_GRAPHICS_IMAGE, OnUpdateGraphicsImage)
ON_UPDATE_COMMAND_UI(ID_GRAPHICS_GRADIENTBRUSH, OnUpdateGraphicsGradientbrush)
ON_COMMAND(ID_GRAPHICS_GRADIENTBRUSH, OnGraphicsGradientbrush)
ON_WM_TIMER()
ON_COMMAND(ID_BUFFERING_NOBUFFERING, OnBufferingNobuffering)
ON_COMMAND(ID_BUFFERING_DOUBLEBUFFERING, OnBufferingDoublebuffering)
ON_COMMAND(ID_GRAPHICS_TEXTANDIMAGE, OnGraphicsTextandimage)
ON_UPDATE_COMMAND_UI(ID_GRAPHICS_TEXTANDIMAGE, OnUpdateGraphicsTextandimage)
ON_COMMAND(ID_GRAPHICS_ROTATEIMAGE, OnGraphicsRotateimage)
ON_UPDATE_COMMAND_UI(ID_GRAPHICS_ROTATEIMAGE, OnUpdateGraphicsRotateimage)

ON_COMMAND(ID_BACKGROUND_CENTER, OnBackgroundCenter)
ON_UPDATE_COMMAND_UI(ID_BACKGROUND_CENTER, OnUpdateBackgroundCenter)
ON_COMMAND(ID_BACKGROUND_STRETCH, OnBackgroundStretch)
ON_UPDATE_COMMAND_UI(ID_BACKGROUND_STRETCH, OnUpdateBackgroundStretch)
END_MESSAGE_MAP()

// CGDIPlusView construction/destruction

CGDIPlusView::CGDIPlusView()
: m_bUp(true)
, m_bRight(true)
, m_radius(30)
, m_bRotate(false)
{
	m_DrawMode = LinearGradient;
	cx=20;
	cy=50;
}

CGDIPlusView::~CGDIPlusView()
{
}

BOOL CGDIPlusView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

// CGDIPlusView drawing

void CGDIPlusView::OnDraw(CDC* /*pDC*/)
{
	CGDIPlusDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

}


// CGDIPlusView diagnostics

#ifdef _DEBUG
void CGDIPlusView::AssertValid() const
{
	CView::AssertValid();
}

void CGDIPlusView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CGDIPlusDoc* CGDIPlusView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGDIPlusDoc)));
	return (CGDIPlusDoc*)m_pDocument;
}
#endif //_DEBUG


// CGDIPlusView message handlers

int CGDIPlusView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	m_nTimer=SetTimer(1000, 50, NULL);
	return 0;
}

void CGDIPlusView::OnPaint()
{
	CPaintDC dc(this); // device context for painting
//	using namespace Gdiplus;
	Graphics graphics(dc.m_hDC); 
	
	CRect rect;
	GetClientRect(&rect);
	switch(m_DrawMode)
	{
	case LinearGradient:
		 {
			Rect rc(rect.left,rect.top,rect.right,rect.bottom);
			LinearGradientBrush linGrBrush(rc, Color(255, 255, 255,255), Color(255, 255, 255,255),LinearGradientModeHorizontal,true);
			LinearGradientBrush linGrBrush1(rc, Color(0, 10, 60,0), Color(255, 20,2, 250),LinearGradientModeHorizontal,true);
			graphics.FillEllipse(&linGrBrush1, cx, cy,m_radius,m_radius);
			Sleep(50);
			graphics.FillEllipse(&linGrBrush, cx,cy,m_radius,m_radius);
			if(m_bUp==true)	
				cy++;
			else
				cy--;

			if((cy+m_radius)==rect.bottom)
				m_bUp=false;
			if(cy==rect.top)
				m_bUp=true;

			if(m_bRight==true)
				cx++;
			else
				cx--;

			if((cx+m_radius)==rect.right)
				m_bRight=false;
			if(cx == rect.left)
				m_bRight=true;
			break;
		}
	case Text:
	{
		Image image(L"image.jpg");
		Rect rc(rect.left,rect.top,rect.right,rect.bottom);
		Rect rct(0, 0, image.GetWidth(), image.GetHeight());
		TextureBrush brush(&image,rct);
		
		FontFamily  fontFamily(L"Times New Roman");
		Font  font(&fontFamily,120, FontStyleItalic|FontStyleBold|FontStyleUnderline, UnitPixel);
		PointF      pointF(5.0f, 15.0f);
		
		graphics.DrawString(L"Hello", -1, &font, pointF, &brush);

		
		if(m_nTimer!=0)
		{		
			KillTimer(m_nTimer);
			m_nTimer=0;
		}
		break;
	}
	case Graphicpath:
	{

		Image image(L"image.jpg");
		Rect rct(0, 0, image.GetWidth(), image.GetHeight());
		TextureBrush brush(&image,rct);
		Pen pen(&brush);
		GraphicsPath gpath;
		gpath.AddBezier(10,20,130,15,160,130,280,50);
		gpath.AddLine(280,50,245,110);

		gpath.AddBezier(230,110,160,100,160,150,30,100);
		gpath.AddLine(30,100,10,100);
		if(m_bRotate)
		{
			for (int i=0;i<20;i++)
			{
				graphics.RotateTransform(i);
				graphics.FillPath(&brush,&gpath);
			}
			m_bRotate=false;
		}
		else 
		{
			graphics.FillPath(&brush,&gpath);
			m_bRotate=true;
		}
		if(m_nTimer!=0)
		{
			KillTimer(m_nTimer);
			m_nTimer=0;
		}
		break;
	}
	case NoBuffering:
	{
		if(m_nTimer!=0)
		{
			KillTimer(m_nTimer);
			m_nTimer=0;
		}
		srand( (unsigned)time( NULL ) );
		int number = rand();
		number /= RAND_MAX + 1; 
		number *= 254;
		SolidBrush brush(Color(255,255,255,255));
		Rect rc(rect.left,rect.top,rect.right,rect.bottom);
		graphics.FillRectangle(&brush,rc);

		for(int x=0; x<rect.right; x++)
		{
			for(int y=0; y<rect.bottom; y++)
			{
				double number = rand();
				number /= RAND_MAX + 1; 
				number *= 254;
				Pen pen(Color(number,number,number,number));
				graphics.DrawLine(&pen,0,0,x,y);
			}
		}
		break;
	}
	case DoubleBufferng:
	{
		if(m_nTimer!=0)
		{
			KillTimer(m_nTimer);
			m_nTimer=0;
		}
		srand( (unsigned)time( NULL ) );
		int number = rand();
		number /= RAND_MAX + 1; 
		number *= 254;

	Rect rc(rect.left,rect.top,rect.right,rect.bottom);
   // Create an Image object from a PNG file.
   Bitmap bmp(rect.right,rect.bottom);

   // Create a Graphics object that is associated with the image.
   Graphics* graph = Graphics::FromImage(&bmp);
   
   // Alter the image.
   SolidBrush brush(Color(255, 55,255, 255));

   graph->FillRectangle(&brush, rc);
		for(int x=0;x<rect.right;x++)
		{
			for(int y=0; y<rect.bottom; y++)
			{
				double number = rand();
				number /= RAND_MAX + 1; 
				number *= 254;
				Pen pen(Color(number,number,number,number));
				graph->DrawLine(&pen,0,0,x,y);
			}
		}
   // Draw the altered image.
		graphics.DrawImage(&bmp,rect.left,rect.top,rect.right,rect.bottom);

	break;
	}
	case(stretch):
	{
		if(m_nTimer!=0)
		{
			KillTimer(m_nTimer);
			m_nTimer=0;
		}
		Image image(L"image1.jpg");
		Rect rct(0,0,rect.right,rect.bottom);
		TextureBrush brush(&image,rct);
		graphics.DrawImage(&image,rct.X,rct.Y,rct.Width,rct.Height);
		break;

	}
	case(center):
	{
		if(m_nTimer!=0)
		{
			KillTimer(m_nTimer);
			m_nTimer=0;
		}
		Image image(L"image1.jpg");
		Rect rct(0,0,rect.right,rect.bottom);
		int a=image.GetWidth();
		int b=image.GetHeight();
		a=rct.Width-a;
		b=rct.Height-b;
		a/=2;
		b/=2;
		a=abs(a);
		b=abs(b);

		Rect rc(a,b,image.GetWidth(),image.GetHeight());
		TextureBrush brush(&image,rct);
		graphics.DrawImage(&image,rc.X,rc.Y,rc.Width,rc.Height);
		break;
	}
	}
}

void CGDIPlusView::OnGraphicsImage()
{
	m_DrawMode = Graphicpath;
	Invalidate();
}

void CGDIPlusView::OnUpdateGraphicsImage(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_DrawMode == Graphicpath);
}

void CGDIPlusView::OnUpdateGraphicsGradientbrush(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_DrawMode == LinearGradient);
}

void CGDIPlusView::OnGraphicsGradientbrush()
{
	m_DrawMode = LinearGradient;
	Invalidate();
	if(m_nTimer==0)
		m_nTimer=SetTimer(1000,50,NULL);
}

void CGDIPlusView::OnTimer(UINT nIDEvent)
{
	Invalidate();
	CView::OnTimer(nIDEvent);
}

void CGDIPlusView::OnBufferingNobuffering()
{
	m_DrawMode = NoBuffering;
	Invalidate();
}

void CGDIPlusView::OnBufferingDoublebuffering()
{
	m_DrawMode = DoubleBufferng;
	Invalidate();
}

void CGDIPlusView::OnGraphicsTextandimage()
{
	m_DrawMode = Text;
	Invalidate();
}

void CGDIPlusView::OnUpdateGraphicsTextandimage(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_DrawMode == Text);
}

void CGDIPlusView::OnGraphicsRotateimage()
{
	m_DrawMode = Graphicpath;
	Invalidate();
	
}

void CGDIPlusView::OnUpdateGraphicsRotateimage(CCmdUI *pCmdUI)
{
		pCmdUI->Enable(m_DrawMode == Graphicpath);
		pCmdUI->SetCheck(!m_bRotate);
}


void CGDIPlusView::OnBackgroundCenter()
{
	m_DrawMode = center;
	Invalidate();
}

void CGDIPlusView::OnUpdateBackgroundCenter(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_DrawMode == center);
}

void CGDIPlusView::OnBackgroundStretch()
{
	m_DrawMode = stretch;
	Invalidate();
}

void CGDIPlusView::OnUpdateBackgroundStretch(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck(m_DrawMode == stretch);
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions