1. 程式人生 > >MFC GDI+顯示GIF檔案

MFC GDI+顯示GIF檔案

在標頭檔案裡面新增
Image* image;
	GUID Guid ;
	UINT frameCount;
	UINT framePos;

介面類的建構函式裡面新增

image = NULL;
	frameCount = 0;
	framePos = 0;

載入GIF檔案
void CFormatDlg::LoadGif()
{
	WCHAR strModule[MAX_PATH * 2] = {0};
	GetModuleFileNameW(NULL, strModule, MAX_PATH * 2);
	::PathRemoveFileSpecW(strModule);
	wsprintfW(strModule + wcslen(strModule), L"\\%s.gif", L"wait");

	image = Image::FromFile(strModule);

	//獲得有多少個維度,對於gif就一個維度
	UINT count = image->GetFrameDimensionsCount();
	GUID *pDimensionIDs = (GUID*)new GUID[count];
	image->GetFrameDimensionsList(pDimensionIDs, count);
	WCHAR strGuid[39];
	StringFromGUID2(pDimensionIDs[0], strGuid, 39);
	frameCount = image->GetFrameCount(&pDimensionIDs[0]);

	delete[] pDimensionIDs;

	//獲得各幀之間的時間間隔
	//先獲得有多少個時間間隔,PropertyTagFrameDelay是GDI+中預定義的一個GIG屬性ID值,表示標籤幀資料的延遲時間
	UINT FrameDelayNums = image->GetPropertyItemSize(PropertyTagFrameDelay);
	PropertyItem* lpPropertyItem = new PropertyItem[FrameDelayNums];
	image->GetPropertyItem(PropertyTagFrameDelay, FrameDelayNums, lpPropertyItem);

	Guid = FrameDimensionTime;
	image->SelectActiveFrame(&Guid, framePos);
}
定時器播放。SetTimer(0, 50, NULL);
void CGIFDlg::OnTimer(UINT_PTR nIDEvent)
{
	if (image){
		Graphics gh(m_hWnd);
		gh.DrawImage(image, 0, 0, image->GetWidth(), image->GetHeight());

		//設定當前需要顯示的幀數
		image->SelectActiveFrame(&Guid, framePos);
		framePos++;
		if (framePos == frameCount){
			framePos = 0;
		}
	}

	CDialogEx::OnTimer(nIDEvent);
}

VS2012工程地址:http://download.csdn.net/detail/sz76211822/9532053

在此說明一下。不要使用網上的CPictureEx 類。為什麼呢。檢視一段呼叫的程式碼:

if (m_GifPic.Load(MAKEINTRESOURCE(IDR_FORMAT), _T("Gif")))	{
			m_GifPic.ShowWindow(SW_SHOW);
			m_GifPic.Draw();
		}
這樣是沒有問題的。正確呼叫了CPictureEx 的成員函式。但是在XP系統下是有問題的。看看 Load成員函式的程式碼:
BOOL CPictureEx::Load(LPCTSTR szResourceName, LPCTSTR szResourceType)
{
 ASSERT(szResourceName);
 ASSERT(szResourceType);

 HRSRC hPicture = FindResource(AfxGetResourceHandle(),szResourceName,szResourceType);
 HGLOBAL hResData;
 if (!hPicture || !(hResData = LoadResource(AfxGetResourceHandle(),hPicture)))
 {
  TRACE(_T("Load (resource): Error loading resource %s\n"),szResourceName);
  return FALSE;
 };
 DWORD dwSize = SizeofResource(AfxGetResourceHandle(),hPicture);

 // hResData is not the real HGLOBAL (we can't lock it)
 // let's make it real

 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD,dwSize);
 if (!hGlobal)
 {
  TRACE(_T("Load (resource): Error allocating memory\n"));
  FreeResource(hResData);
  return FALSE;
 };
 
 char *pDest = reinterpret_cast<char *> (GlobalLock(hGlobal));
 char *pSrc = reinterpret_cast<char *> (LockResource(hResData));
 if (!pSrc || !pDest)
 {
  TRACE(_T("Load (resource): Error locking memory\n"));
  GlobalFree(hGlobal);
  FreeResource(hResData);
  return FALSE;
 };
 CopyMemory(pDest,pSrc,dwSize);
 FreeResource(hResData);
 GlobalUnlock(hGlobal);

 BOOL bRetValue = Load(hGlobal,dwSize);
 GlobalFree(hGlobal);
 return bRetValue;
}
經過打斷點,在xp系統中執行到CopyMemory總是莫名其妙的停止了,然後程式退出~~。