最近正在用duilib進行開發,需要顯示動態的gif.由於新版的stb_image.c中,還沒有支持動態gif的加載,本人決定在stb_image.c中增加一個加載動態gif的函數TGifInfo*gif_load_from_memory().
下面說說關鍵的地方吧.可以把動態gif簡單的理解爲:gif文件是由多張普通的bmp圖片組成,顯示第1張BMP,延時一段時間,顯示第二張,延時一段時間,顯示第3張…
動態gif文件中的每幅圖片,我們可以用這樣的結構到保存:
再用一個類來保存所有的TImageInfo 信息
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格式:
所以如果要在CListUI中顯示動畫,記得寫回調並把this指針傳給create函數。