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总是莫名其妙的停止了,然后程序退出~~。


动态加载GIF动画 VC 实现 include "stdafx.h" #include "TransparentGif.h" #include "TransparentGifDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CTransparentGifApp BEGIN_MESSAGE_MAP(CTransparentGifApp, CWinAppEx) ON_COMMAND(ID_HELP, &CWinApp::OnHelp) END_MESSAGE_MAP() // CTransparentGifApp 构造 CTransparentGifApp::CTransparentGifApp() { // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 } // 唯一的一个 CTransparentGifApp 对象 CTransparentGifApp theApp; // CTransparentGifApp 初始化 BOOL CTransparentGifApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls; InitCtrls.dwSize = sizeof(InitCtrls); // 将它设置为包括所有要在应用程序中使用的 // 公共控件类。 InitCtrls.dwICC = ICC_WIN95_CLASSES; InitCommonControlsEx(&InitCtrls); CWinAppEx::InitInstance(); AfxEnableControlContainer(); // 标准初始化 // 如果未使用这些功能并希望减小 // 最终可执行文件的大小,则应移除下列 // 不需要的特定初始化例程 // 更改用于存储设置的注册表项 // TODO: 应适当修改该字符串, // 例如修改为公司或组织名 SetRegistryKey(_T("应用程序向导生成的本地应用程序")); CTransparentGifDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: 在此放置处理何时用 // “确定”来关闭对话框的代码 } else if (nResponse == IDCANCEL) { // TODO: 在此放置处理何时用 // “取消”来关闭对话框的代码 } // 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序, // 而不是启动应用程序的消息泵。 return FALSE; }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值