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.
#include<gdiplus.h />
using namespace Gdiplus;
#pragma comment(lib,"gdiplus.lib")
Before using GDI+ in your application, you should initialize the enviroment code below:
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
Status state = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Correspondent to initialize, you should clean up the environment.
GdiplusShutdown(gdiplusToken);
Critical Code
void CGIFControl::Load(LPCTSTR sFileName)
{
m_pImage = new Image(sFileName);
UINT count = m_pImage->GetFrameDimensionsCount();
m_pDimensionIDs =new GUID[count];
m_pImage->GetFrameDimensionsList(m_pDimensionIDs, count);
WCHAR strGuid[39];
StringFromGUID2(m_pDimensionIDs[0], strGuid, 39);
m_FrameCount = m_pImage->GetFrameCount(&m_pDimensionIDs[0]);
UINT TotalBuffer = m_pImage->GetPropertyItemSize(PropertyTagFrameDelay);
m_pItem = (PropertyItem*)malloc(TotalBuffer);
m_pImage->GetPropertyItem(PropertyTagFrameDelay,TotalBuffer,m_pItem);
}
void CGIFControl::Play()
{
m_iCurrentFrame = 0;
GUID Guid = FrameDimensionTime;
m_pImage->SelectActiveFrame(&Guid,m_iCurrentFrame);
SetTimer(1,((UINT*)m_pItem[0].value)[m_iCurrentFrame] * 10,NULL);
++ m_iCurrentFrame;
Invalidate(FALSE);
}
void CGIFControl::OnTimer(UINT_PTR nIDEvent)
{
KillTimer(nIDEvent);
GUID Guid = FrameDimensionTime;
m_pImage->SelectActiveFrame(&Guid,m_iCurrentFrame);
SetTimer(1,((UINT*)m_pItem[0].value)[m_iCurrentFrame] * 10,NULL);
m_iCurrentFrame = (++ m_iCurrentFrame) % m_FrameCount;
Invalidate(FALSE);
}
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.