Gif. h
[Cpp]
Class CGIFImage: public CStatic
{
// Construction
Public:
CGIFImage ();
Void LoadGIF (WCHAR *);
Void Pause ();
Void Resume ();
Int m_state;
// Attributes
Private:
Struct _ sTHPar
{
Image * m_Img;
PropertyItem * m_item;
Int m_Count;
HWND m_hWnd;
} SThPar;
Image * m_Img;
DWORD m_ThreadId;
Public:
// Operations
Public:
// Overrides
// ClassWizard generated virtual function overrides
// {AFX_VIRTUAL (CGIFImage)
//} AFX_VIRTUAL
// Implementation
Public:
Virtual ~ CGIFImage ();
// Generated message map functions
Protected:
// {AFX_MSG (CGIFImage)
Afx_msg void OnPaint ();
//} AFX_MSG
Static dword winapi DrawGIF (LPVOID );
DECLARE_MESSAGE_MAP ()
};
Gif. cpp
[Cpp]
CGIFImage: CGIFImage ()
{
M_ThreadId = 0;
M_Img = 0;
M_state =-1;
}
CGIFImage ::~ CGIFImage ()
{
If (m_ThreadId)
{
: PostThreadMessage (m_ThreadId, WM_GIFSTOP, 0, 0 );
}
}
BEGIN_MESSAGE_MAP (CGIFImage, CStatic)
// {AFX_MSG_MAP (CGIFImage)
ON_WM_PAINT ()
//} AFX_MSG_MAP
END_MESSAGE_MAP ()
//////////////////////////////////////// /////////////////////////////////////
// CGIFImage message handlers
Void CGIFImage: OnPaint ()
{
CPaintDC dc (this); // device context for painting
// TODO: Add your message handler code here
If (m_ThreadId & m_Img)
{
RECT rWin;
GetClientRect (& rWin );
RectF rF (rWin. left, rWin. top, rWin. right, rWin. bottom );
Graphics gh (dc. m_hDC );
Gh. DrawImage (m_Img, rF, 0, 0, m_Img-> GetWidth (), m_Img-> GetHeight (), UnitPixel );
}
// Do not call CStatic: OnPaint () for painting messages
}
Void CGIFImage: LoadGIF (WCHAR * wzFile)
{
If (m_ThreadId)
{
: PostThreadMessage (m_ThreadId, WM_GIFSTOP, 0, 0 );
}
M_Img = Image: FromFile (wzFile, FALSE );
UINT count = m_Img-> GetFrameDimensionsCount ();
GUID * pDimensionIDs = (GUID *) new GUID [count];
M_Img-> GetFrameDimensionsList (pDimensionIDs, count );
WCHAR strGuid [39];
StringFromGUID2 (pDimensionIDs [0], strGuid, 39 );
UINT frameCount = m_Img-> GetFrameCount (& pDimensionIDs [0]);
Delete [] pDimensionIDs;
UINT FrameDelayNums = m_Img-> GetPropertyItemSize (PropertyTagFrameDelay );
PropertyItem * lpPropertyItem = new PropertyItem [FrameDelayNums];
M_Img-> GetPropertyItem (PropertyTagFrameDelay, FrameDelayNums, lpPropertyItem );
_ STHPar * sP = new _ sTHPar;
SP-> m_hWnd = m_hWnd;
SP-> m_Img = m_Img;
SP-> m_Count = frameCount;
SP-> m_item = lpPropertyItem;
CreateThread (0, 0, DrawGIF, sP, 0, & m_ThreadId );
M_state = 1;
}
Dword winapi CGIFImage: DrawGIF (LPVOID l)
{
_ STHPar * par = (_ sTHPar *) l;
Int FrameCount = 0;
Long lPause = 0;
HDC dc =: GetWindowDC (par-> m_hWnd );
RECT rWin;
: GetClientRect (par-> m_hWnd, & rWin );
RectF rF (rWin. left, rWin. top, rWin. right, rWin. bottom );
GUID Guid = FrameDimensionTime;
Par-> m_Img-> SelectActiveFrame (& Guid, FrameCount );
Graphics gh (dc );
Gh. DrawImage (par-> m_Img, rF, 0,0, par-> m_Img-> GetWidth (), par-> m_Img-> GetHeight (), UnitPixel );
DWORD dTick = GetTickCount ();
LPause = (long *) par-> m_item-> value) [FrameCount] * 10;
While (1)
{
Sleep (1 );
MSG msg;
If (PeekMessage (& msg, 0, 0, PM_REMOVE ))
{
If (msg. message = WM_GIFSTOP)
{
: ReleaseDC (par-> m_hWnd, dc );
Delete par-> m_Img;
Delete [] par-> m_item;
Delete par;
Return 0;
}
}
Else
{
If (par-> m_Count> 1)
{
If (GetTickCount ()-dTick> = lPause)
{
If (FrameCount + 1) = par-> m_Count)
{
FrameCount = 0;
Par-> m_Img-> SelectActiveFrame (& Guid, 0 );
}
Else
{
Par-> m_Img-> SelectActiveFrame (& Guid, ++ FrameCount );
}
Graphics gh (dc );
Gh. DrawImage (par-> m_Img, rF, 0,0, par-> m_Img-> GetWidth (), par-> m_Img-> GetHeight (), UnitPixel );
LPause = (long *) par-> m_item-> value) [FrameCount] * 10;
DTick = GetTickCount ();
}
}
}
}
Return 0;
}
Void CGIFImage: Pause ()
{
If (m_ThreadId)
{
Typedef HANDLE (WINAPI * OPENTHREAD) (DWORD, BOOL, DWORD );
OPENTHREAD lpfnOpenThread = (OPENTHREAD) GetProcAddress (LoadLibrary ("kernel32.dll"), "OpenThread ");
HANDLE hThread = lpfnOpenThread (THREAD_ALL_ACCESS, FALSE, m_ThreadId );
SuspendThread (hThread );
M_state = 0;
}
}
Void CGIFImage: Resume ()
{
If (m_ThreadId)
{
Typedef HANDLE (WINAPI * OPENTHREAD) (DWORD, BOOL, DWORD );
OPENTHREAD lpfnOpenThread = (OPENTHREAD) GetProcAddress (LoadLibrary ("kernel32.dll"), "OpenThread ");
HANDLE hThread = lpfnOpenThread (THREAD_ALL_ACCESS, FALSE, m_ThreadId );
ResumeThread (hThread );
M_state = 1;
}
}