下面说说关键的地方吧.可以把动态gif简单的理解为:gif文件是由多张普通的bmp图片组成,显示第1张BMP,延时一段时间,显示第二张,延时一段时间,显示第3张...
动态gif文件中的每幅图片,我们可以用这样的结构到保存:
- typedef struct tagTImageInfo
- {
- HBITMAP hBitmap; //位图句柄
- int nX; //位图宽
- int nY; //位图高
- int delay; //延时时间,单位ms
- bool alphaChannel;//是否支持透明
- CStdString sResType;
- DWORD dwMask; //透明颜色值
- } TImageInfo;
再用一个类来保存所有的TImageInfo 信息
- class CGifHandler
- {
- public:
- CGifHandler();
- virtual ~CGifHandler();
- int GetFrameCount();
- void AddFrameInfo(TImageInfo* pFrameInfo);
- TImageInfo* GetNextFrameInfo();
- TImageInfo* GetCurrentFrameInfo();
- TImageInfo* GetFrameInfoAt(int index);
- private:
- CStdPtrArray ImageInfos;
- int nCurrentFrame;
- int nFrameCount;
- bool isDeleting;
- };
好了得到了动态gif文件的数据,下面就剩怎么显示了.我是通过定时器来做延时的.
在duilib中扩展了duilib中的CButtonUI,封装了CButtonGifUI.上图了,大家看看效果.
附件下载:Duilib实现加载gif图(附件包括改写的stb_image.c,加载gif源码,还有一个演示程序)
使用时需要在virtual DuiLib::CControlUI* CreateControl(LPCTSTR pstrClass);中加入以下代码:
- CControlUI* WindowBase::CreateControl(LPCTSTR pstrClass)
- {
- if( _tcscmp(pstrClass, L"ButtonGif") == 0 )
- {
- return new CButtonGifUI;
- }
- return NULL;
- }
用到ButtonGif类的都要实现接口, public IDialogBuilderCallback
并在创建是,把this指针传过去。
CControlUI* pRoot = builder.Create(_T("mainWindow.xml"), (UINT)0, this, &m_paintManager);
原因:研究源码就知道,此回调是用来生成非DuiLib原有控件类时调用。
在CDialogBuilder::_Parse函数中有这样一段代码
if( pControl == NULL && m_pCallback != NULL ) {
pControl = m_pCallback->CreateControl(pstrClass);
}
XML格式:<ButtonGif name="loginloading" pos="60,100,0,0" float="true" height="140" width="140" align="center" NormalGifFile="loading.gif"/>
所以如果要在CListUI中显示动画,记得写回调并把this指针传给create函数。