在windows mobile 平台加载GIF动画,鉴于网上给出的代码不完整或不全,特此整理,废话不多说了,直接进入正题,给出代码吧!
//CGifManage.h
#pragma once
#ifndef __CGIFMANAGE_H_H
#define __CGIFMANAGE_H_H
interface IImagingFactory;
interface IImageDecoder;
interface IImage;
interface IStream;
class PropertyItem;
class CGifManage
{
public:
CGifManage(void);
~CGifManage(void);
BOOL SetOwnerTimer(HWND hWnd,UINT nIDEvent,UINT uElapse,TIMERPROC lpTimerFunc);
static void CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
// BOOL KillOwnerTimer(HWND hWnd, UINT uIDEvent);
void Display(HWND hWnd,HDC hdc, RECT rcDest);
BOOL LoadGif(LPCWSTR lpFilePath);
private:
IImagingFactory * m_pImagingFactory;
IImageDecoder * m_pDecoder;
IImage *m_pImage;
IBitmapImage* m_pBitImage;
IImageSink* m_pImageSink;
IStream *m_pIstream;
GUID* m_pDimensionIDs;
static UINT m_iFrameCount;
static UINT m_iCurrentFrame;
PropertyItem* m_pItem;
};
#endif
//CGifManage.cpp
#include "StdAfx.h"
#include <imaging.h>
#include <initguid.h>
#include <imgguids.h>
#include <Objbase.h>
#include "CGifManage.h"
#include <malloc.h>
UINT CGifManage::m_iFrameCount=0;
UINT CGifManage::m_iCurrentFrame=0;
CGifManage::CGifManage(void)
{
m_pImagingFactory=NULL;
m_pImage=NULL;
m_pIstream=NULL;
m_pItem=NULL;
m_pDecoder=NULL;
m_pDimensionIDs=NULL;
}
CGifManage::~CGifManage(void)
{
if (m_pImagingFactory)
{
m_pImagingFactory->Release();
}
if (m_pDecoder)
{
m_pDecoder->Release();
}
if (m_pImage)
{
m_pImage->Release();
}
if (m_pBitImage)
{
m_pBitImage->Release();
}
if (m_pImageSink)
{
m_pImageSink->Release();
}
if (m_pIstream)
{
m_pIstream->Release();
}
delete []m_pDimensionIDs;
delete []m_pItem;
}
void CGifManage::Display(HWND hWnd,HDC hdc,RECT rcDest)
{
m_pDecoder->SelectActiveFrame(&m_pDimensionIDs[0],CGifManage::m_iCurrentFrame);
m_pDecoder->BeginDecode(m_pImageSink, NULL);
m_pDecoder->Decode();
m_pDecoder->EndDecode(S_OK);
m_pImage->Draw(hdc,&rcDest, NULL);
//Use Timer
//NOTE HERE: frame-delay values should be multiply by 10
SetOwnerTimer(hWnd,1,((UINT*)m_pItem[0].value)[m_iCurrentFrame]*10,CGifManage::TimerProc);
}
BOOL CGifManage::LoadGif(LPCWSTR lpFilePath)
{
HANDLE hFile = CreateFile(lpFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
if ( (DWORD)-1 == dwFileSize )
{
CloseHandle(hFile);
return FALSE;
}
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize);
if (hGlobal == NULL)
{
CloseHandle(hFile);
return FALSE;
}
LPVOID pvData = GlobalLock(hGlobal);
if (pvData == NULL)
{
GlobalUnlock(hGlobal);
CloseHandle(hFile);
return FALSE;
}
DWORD dwBytesRead = 0;
BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL);
GlobalUnlock(hGlobal);
CloseHandle(hFile);
if (!bRead)
{
return FALSE;
}
if ( FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &m_pIstream)) )
{
return FALSE;
}
if (NULL == m_pImagingFactory)
{
if(FAILED( CoCreateInstance(CLSID_ImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IImagingFactory,
(void**) &m_pImagingFactory)))
{
m_pImagingFactory = NULL;
return false;
}
}
if ( !SUCCEEDED(m_pImagingFactory->CreateImageDecoder(m_pIstream,DecoderInitFlagBuiltIn1st, &m_pDecoder)) )
{
return FALSE;
}
ImageInfo iif;
m_pDecoder->GetImageInfo(&iif);
m_pImagingFactory->CreateNewBitmap(iif.Width,iif.Height,iif.PixelFormat,&m_pBitImage);
m_pBitImage->QueryInterface(IID_IImageSink,(void**)&m_pImageSink);
m_pBitImage->QueryInterface(IID_IImage,(void**)&m_pImage);
UINT count =0;
m_pDecoder->GetFrameDimensionsCount(&count);
m_pDimensionIDs =(GUID*)new GUID[count];
m_pDecoder->GetFrameDimensionsList(m_pDimensionIDs, count);
WCHAR strGuid[39];
StringFromGUID2(m_pDimensionIDs[0], strGuid, 39);
m_pDecoder->GetFrameCount(&m_pDimensionIDs[0],&m_iFrameCount);
//PropertyTagFrameDelay是GDI+中预定义的一个GIG属性ID值,表示标签帧数据的延迟时间
UINT TotalBuffer =0;
m_pDecoder->GetPropertyItemSize(PropertyTagFrameDelay,&TotalBuffer);
m_pItem = (PropertyItem*)malloc(TotalBuffer);
m_pDecoder->GetPropertyItem(PropertyTagFrameDelay,TotalBuffer,m_pItem);
return TRUE;
}
BOOL CGifManage::SetOwnerTimer(HWND hWnd,UINT nIDEvent,UINT uElapse,TIMERPROC lpTimerFunc)
{
UINT result=SetTimer(hWnd,nIDEvent,uElapse,lpTimerFunc);
if (0!=result)
{
return TRUE;
}
else
return FALSE;
}
void CALLBACK CGifManage::TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
KillTimer(hwnd,idEvent);
//Again move to the next
CGifManage::m_iCurrentFrame = (++CGifManage::m_iCurrentFrame)%m_iFrameCount;
InvalidateRect(hwnd,NULL,FALSE);
}
//BOOL CGifManage::KillOwnerTimer(HWND hWnd, UINT uIDEvent)
//{
// UINT result=KillTimer(hWnd,uIDEvent);
// if (0!=result)
// {
// return TRUE;
// }
// else
// return FALSE;
//}
至于COM组建的初始化CoInitializeEx(NULL,COINIT_MULTITHREADED)大家都知道该怎么用了吧!呵呵!
参考资料如下,对于给出的帮助说声谢谢!
http://blog.csdn.net/kekobobo/archive/2009/07/02/4316017.aspx
http://www.codeproject.com/KB/GDI-plus/gdiplusgif.aspx
http://pyud123456.blog.163.com/blog/static/8520221720091184016702/
http://www.qqgb.com/Program/VC/VCmultimedia/Program_104521_6.html
http://www.cnblogs.com/wangkewei/archive/2009/10/11/1580937.html
http://hi.baidu.com/coolzdp/blog/item/a05433ad231691004a36d6c0.html
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wqbyangtzeu/archive/2010/01/13/5186253.aspx