Source code
# Pragma once
# Include <gdiplus. h>
# Pragma comment (Lib, "gdiplus. lib ")
Using namespace gdiplus;
Class gifimage: public image
{
Public:
Gifimage (maid, maid );
Gifimage (const wchar * filename, bool useembeddedcolormanagement = false );
~ Gifimage ();
Void getsize (size * psize );
Bool isanimatedgif () {return m_nframecount> 1 ;}
Void setpause (bool bpause );
Bool ispaused () {return m_bpause ;}
Bool initanimation (hwnd, point pt );
Void threadanimation ();
Void destroy ();
Protected:
Bool testforanimatedgif ();
Void initialize ();
Bool drawframegif ();
Bool loadfrombuffer (byte * pbuff, int nsize );
Bool getresource (lpname, lptype, void * presource, Int & nbufsize );
Bool load (maid, maid );
Istream * m_pstream;
Handle m_hthread;
Handle m_hpause;
Handle m_hexitevent;
Hinstance m_hinst;
Hwnd m_hwnd;
Uint m_nframecount;
Uint m_nframeposition;
Bool m_bisinitialized;
Bool m_bpause;
Propertyitem * m_ppropertyitem;
Point m_pt;
};
// Gdiplushelper. cpp: Implementation of the cgdiplushelper class.
//
//////////////////////////////////////// //////////////////////////////
# Include "stdafx. H"
# Include "gifimage. H"
# Include <process. h>
Gifimage: gifimage (maid, maid)
{
Initialize ();
If (load (sresourcetype, sresource ))
{
Nativeimage = NULL;
Lastresult = dllexports: gdiploadimagefromstreamicm (m_pstream, & nativeimage );
Testforanimatedgif ();
}
}
Gifimage: gifimage (const wchar * filename, bool useembeddedcolormanagement): image (filename, useembeddedcolormanagement)
{
Initialize ();
M_bisinitialized = true;
Testforanimatedgif ();
}
Gifimage ::~ Gifimage ()
{
Destroy ();
}
DWORD winapi threadanimationproc (lpvoid pparam)
{
Gifimage * pimage = (gifimage *) (pparam );
Pimage-> threadanimation ();
Return 0;
}
Bool gifimage: initanimation (hwnd, point pt)
{
M_hwnd = hwnd;
M_pt.x = pt. X;
M_pt.y = pt. Y;
If (! M_bisinitialized)
{
Return false;
}
If (isanimatedgif ())
{
If (m_hthread = NULL)
{
DWORD ntid = 0;
M_hthread = createthread (null, 0, threadanimationproc, this, create_suincluded, & ntid );
If (! M_hthread)
{
Return true;
}
Else resumethread (m_hthread );
}
}
Return false;
}
Bool gifimage: loadfrombuffer (byte * pbuff, int nsize)
{
Bool bresult = false;
Hglobal = globalalloc (gmem_moveable, nsize );
If (hglobal)
{
Void * pdata = globallock (hglobal );
If (pdata) memcpy (pdata, pbuff, nsize );
Globalunlock (hglobal );
If (createstreamonhglobal (hglobal, true, & m_pstream) = s_ OK) bresult = true;
}
Return bresult;
}
Bool gifimage: getresource (maid, maid, void * presource, Int & nbufsize)
{
Hrsrc hresinfo;
Handle hres;
Lpstr lpres = NULL;
Int nlen = 0;
Bool bresult = false;
// Search for resources
Hresinfo = findresource (m_hinst, lpname, lptype );
If (hresinfo = NULL)
{
DWORD dwerr = getlasterror ();
Return false;
}
// Load Resources
Hres = loadresource (m_hinst, hresinfo );
If (hres = NULL) return false;
// Lock the resource
Lpres = (char *) lockresource (hres );
If (lpres! = NULL)
{
If (presource = NULL)
{
Nbufsize = sizeofresource (m_hinst, hresinfo );
Bresult = true;
}
Else
{
If (nbufsize> = (INT) sizeofresource (m_hinst, hresinfo ))
{
Memcpy (presource, lpres, nbufsize );
Bresult = true;
}
}
Unlockresource (hres );
}
// Release resources
Freeresource (hres );
Return bresult;
}
Bool gifimage: load (maid, maid)
{
Bool bresult = false;
Byte * pbuff = NULL;
Int nsize = 0;
If (getresource (sresource, sresourcetype, pbuff, nsize ))
{
If (nsize> 0)
{
Pbuff = new byte [nsize];
If (getresource (sresource, sresourcetype, pbuff, nsize ))
{
If (loadfrombuffer (pbuff, nsize ))
{
Bresult = true;
}
}
Delete [] pbuff;
}
}
M_bisinitialized = bresult;
Return bresult;
}
Void gifimage: getsize (size * psize)
{
Psize-> Cx = getwidth ();
Psize-> Cy = getheight ();
}
Bool gifimage: testforanimatedgif ()
{
Uint COUNT = 0;
Count = getframedimensionscount ();
Guid * pdimensionids = new guid [count];
// Obtain the frame dimension list
Getframedimensionslist (pdimensionids, count );
// Obtain the number of frames in the first frame dimension.
M_nframecount = getframecount (& pdimensionids [0]);
// Get the attribute item size
Int nsize = getpropertyitemsize (propertytagframedelay );
// Allocate a buffer for the attribute item
M_ppropertyitem = (propertyitem *) malloc (nsize );
Getpropertyitem (propertytagframedelay, nsize, m_ppropertyitem );
Delete pdimensionids;
Return m_nframecount> 1;
}
Void gifimage: Initialize ()
{
M_pstream = NULL;
M_nframeposition = 0;
M_nframecount = 0;
M_pstream = NULL;
Lastresult = invalidparameter;
M_hthread = NULL;
M_bisinitialized = false;
M_ppropertyitem = NULL;
M_hinst = NULL;
M_bpause = false;
M_hexitevent = createevent (null, true, false, null );
M_hpause = createevent (null, true, true, null );
}
Void gifimage: threadanimation ()
{
M_nframeposition = 0;
Bool bexit = false;
While (bexit = false)
{
Bexit = drawframegif ();
}
}
Bool gifimage: drawframegif ()
{
Waitforsingleobject (m_hpause, infinite );
Guid pageguid = framedimensiontime;
Long hmwidth = getwidth ();
Long hmheight = getheight ();
HDC = getdc (m_hwnd );
If (HDC)
{
Graphics graphics (HDC );
Graphics. drawimage (this, m_pt.x, m_pt.y, hmwidth, hmheight );
Releasedc (m_hwnd, HDC );
}
Selectactiveframe (& pageguid, m_nframeposition ++ );
If (m_nframeposition = m_nframecount) m_nframeposition = 0;
Long lpause = (long *) m_ppropertyitem-> value) [m_nframeposition] * 10;
DWORD dwerr = waitforsingleobject (m_hexitevent, lpause );
Return dwerr = wait_object_0;
}
Void gifimage: setpause (bool bpause)
{
If (! Isanimatedgif () return;
If (bpause &&! M_bpause)
{
Resetevent (m_hpause );
}
Else
{
If (m_bpause &&! Bpause)
{
Setevent (m_hpause );
}
}
M_bpause = bpause;
}
Void gifimage: Destroy ()
{
If (m_hthread)
{
Setpause (false );
Setevent (m_hexitevent );
Waitforsingleobject (m_hthread, infinite );
}
Closehandle (m_hthread );
Closehandle (m_hexitevent );
Closehandle (m_hpause );
Free (m_ppropertyitem );
M_ppropertyitem = NULL;
M_hthread = NULL;
M_hexitevent = NULL;
M_hpause = NULL;
If (m_pstream) m_pstream-> release ();
}
Usage
Add when window initialization (you need to add GIF image resources first, "GIF", "Hearts ")
Gifimage * m_image;
M_image = new gifimage ("GIF", "Hearts ");
Crect RC;
Getclientrect (RC );
Int Cx = (RC. Width ()-m_image-> getwidth ()/2;
M_image-> initanimation (m_hwnd, cpoint (CX, 10 ));