Click here to Skip to main content
11,584,460 members (65,309 online)
Click here to Skip to main content

Play GIF using GDI+

, 1 Sep 2011 CPOL 42K 2.3K 55
Rate this:
Please Sign up or sign in to vote.
A new choice for playing GIF using GDI+

Introduction

In the past, there was no convenient enough way to play GIF using functions provided by Microsoft Windows but you may need a reference of 3rd libs. Well, now we have an alternative choice from using GDI+

Base of GDI+

First of all, you need to include GDI+ headers, link the libs and using the namespace. In my sample, I did it in stdafx.h.

//GDI+ references
#include<gdiplus.h />
using namespace Gdiplus;
#pragma comment(lib,"gdiplus.lib")

Before using GDI+ in your application, you should initialize the enviroment code below:

//Init GDI+
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Status state = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

Correspondent to initialize, you should clean up the environment.

GdiplusShutdown(gdiplusToken);

Critical Code

//Here, we load a GIF image file
void CGIFControl::Load(LPCTSTR sFileName)
{
	m_pImage = new Image(sFileName);
	
	//First of all we should get the number of frame dimensions
	//Images considered by GDI+ as:
	//frames[animation_frame_index][how_many_animation];
	UINT count = m_pImage->GetFrameDimensionsCount();

	//Now we should get the identifiers for the frame dimensions 
	m_pDimensionIDs =new GUID[count];
	m_pImage->GetFrameDimensionsList(m_pDimensionIDs, count);
	
	//For gif image , we only care about animation set#0
	WCHAR strGuid[39];
	StringFromGUID2(m_pDimensionIDs[0], strGuid, 39);
	m_FrameCount = m_pImage->GetFrameCount(&m_pDimensionIDs[0]);

	//PropertyTagFrameDelay is a pre-defined identifier 
	//to present frame-delays by GDI+
	UINT TotalBuffer = m_pImage->GetPropertyItemSize(PropertyTagFrameDelay);
	m_pItem = (PropertyItem*)malloc(TotalBuffer);
	m_pImage->GetPropertyItem(PropertyTagFrameDelay,TotalBuffer,m_pItem);
}

//To start play
void CGIFControl::Play()
{
	//Set Current Frame at #0
	m_iCurrentFrame = 0;
	GUID Guid = FrameDimensionTime;
	m_pImage->SelectActiveFrame(&Guid,m_iCurrentFrame);

	//Use Timer
	//NOTE HERE: frame-delay values should be multiply by 10
	SetTimer(1,((UINT*)m_pItem[0].value)[m_iCurrentFrame]  * 10,NULL);

	//Move to the next frame
	++ m_iCurrentFrame;
	Invalidate(FALSE);
}

//Using timer
void CGIFControl::OnTimer(UINT_PTR nIDEvent)
{
	//Because there will be a new delay value
	KillTimer(nIDEvent);

	//Change Active frame
	GUID Guid = FrameDimensionTime;
	m_pImage->SelectActiveFrame(&Guid,m_iCurrentFrame);

	//New timer
	SetTimer(1,((UINT*)m_pItem[0].value)[m_iCurrentFrame] * 10,NULL);

	//Again move to the next
	m_iCurrentFrame = (++ m_iCurrentFrame) % m_FrameCount;
	Invalidate(FALSE);
}

//Present current frame
void CGIFControl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	Graphics g(lpDrawItemStruct->hDC);

	DrawBorder(g);

	CRect rcClient;
	GetClientRect(&rcClient);

	if(m_bBorderEnable)
	{
		rcClient.DeflateRect(m_iBorderLineWidth,
			m_iBorderLineWidth,m_iBorderLineWidth,m_iBorderLineWidth);
	}

	g.DrawImage(m_pImage,rcClient.left,rcClient.top,rcClient.Width(),
			rcClient.Height());
}

Using the Code

Step 1: Set control correspondence in DoDataExchange method of sample dialog:

DDX_Control(pDX,IDC_GIF_PLAY,m_Gif);

Step 2: Load the gif image in OnInitDialog:

m_Gif.Load(_T("Sample.gif"));

Finally, add start and finish code in button event handler:

void CGifControlSampleDlg::OnBnClickedBtnPlay()
{
	m_Gif.Play();
}

void CGifControlSampleDlg::OnBnClickedBtnStop()
{
	m_Gif.Stop();
}

About the Source

Binary files in attachment archive are compiled by VS2005SP1, so you may need to install the suit vcredist package by yourself first.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Yi Li
China China
No Biography provided

You may also be interested in...

Comments and Discussions

 
QuestionWindow flickers a lot Pin
apurv14626-May-15 1:14
memberapurv14626-May-15 1:14 
QuestionGuard Page exception Pin
Member 105681415-Mar-14 0:13
memberMember 105681415-Mar-14 0:13 
GeneralMy vote of 4 Pin
shetkarabhijeet23-Nov-12 6:56
membershetkarabhijeet23-Nov-12 6:56 
QuestionAbout interval of timer Pin
georgezzt12-Apr-12 15:21
membergeorgezzt12-Apr-12 15:21 
GeneralMy vote of 5 Pin
Abu Mami19-Feb-12 1:13
memberAbu Mami19-Feb-12 1:13 
GeneralMy vote of 5 Pin
Tage Lejon6-Sep-11 5:27
memberTage Lejon6-Sep-11 5:27 
GeneralRe: My vote of 5 Pin
Yi Li6-Sep-11 6:31
memberYi Li6-Sep-11 6:31 
QuestionNo copy,thx! Pin
Aric Green4-Sep-11 22:51
memberAric Green4-Sep-11 22:51 
AnswerRe: No copy,thx! Pin
Yi Li6-Sep-11 6:24
memberYi Li6-Sep-11 6:24 
Questionsame code Pin
merano23-Aug-11 7:26
membermerano23-Aug-11 7:26 
AnswerRe: same code Pin
Yi Li31-Aug-11 21:54
memberYi Li31-Aug-11 21:54 
Questionvery bad doku Pin
merano23-Aug-11 6:50
membermerano23-Aug-11 6:50 
AnswerRe: very bad doku Pin
Yi Li31-Aug-11 22:01
memberYi Li31-Aug-11 22:01 
GeneralJust a suggestion Pin
sandeepkavade19-Nov-08 18:38
membersandeepkavade19-Nov-08 18:38 
GeneralRe: Just a suggestion Pin
Yi Li6-Sep-11 6:33
memberYi Li6-Sep-11 6:33 
GeneralWhich Library Pin
Dileep.M1-Jul-08 2:04
memberDileep.M1-Jul-08 2:04 
GeneralRe: Which Library Pin
Yi Li1-Jul-08 17:14
memberYi Li1-Jul-08 17:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 1 Sep 2011
Article Copyright 2008 by Yi Li
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid