Duilib是不支持Gif,而网上也有很多方法实现,这里说的是一种更加直接的方法,不需要修改duilib的库,直接按照duilib的内部机制实现gif的显示,
另一方面就是增加了资源管理类,同一个资源不会重复加载
原理:通过GDI+把gif分解,得到每帧图片和间隔时间,然后通过定时器按照间隔时间触发区域刷新,最后重载控件的绘制函数,让他绘制每帧图片
实现:
第一步分解:
bool GetData(CString strFile)
{
//装载gif文件
image = Image::FromFile(strFile);
if(image == NULL)
return false;
//得到帧数
UINT count=0;
count=image->GetFrameDimensionsCount();
GUID *pDimensionIDs=(GUID*)new GUID[count];
image->GetFrameDimensionsList(pDimensionIDs,count);
frameCount=image->GetFrameCount(&pDimensionIDs[0]);
delete []pDimensionIDs;
//得到每帧属性
int size=image->GetPropertyItemSize(PropertyTagFrameDelay);
PropertyItem*pItem = NULL;
pItem=(PropertyItem*)malloc(size);
if(pItem == NULL)
return false;
image->GetPropertyItem(PropertyTagFrameDelay,size,pItem);
Guid= Gdiplus::FrameDimensionTime;
nSleep=((long*)pItem->value)[0]*10;
return true;
}
第二步触发:
void CDuilibHDCUI4Gif::Notify(TNotifyUI& msg)
{
CString strType = msg.sType;
if(msg.pSender == this)
{
if (strType == _T("timer"))
{
Invalidate();
}
}
}
第三步处理:
void CDuilibHDCUI4Gif::PaintBkImage(HDC hDC)
{
Graphics graphics(hDC);
graphics.DrawImage(m_pGD->image,
m_rcPaint.left,m_rcPaint.top, m_rcPaint.right - m_rcPaint.left,m_rcPaint.bottom - m_rcPaint.top);
m_pGD->image->SelectActiveFrame(&m_pGD->Guid,m_pGD->fcount++);
if(m_pGD->fcount == m_pGD->frameCount)
m_pGD->fcount = 0;
}
第四步应用:
*.xml
<Container float="true" adaptive="true" pos="158, 76,0,0" width="210" height="145" >
<DuilibHDCUI4Gif giffile="my.gif" />
</Container>
or
<DuilibHDCUI4Gif giffile="my.gif" float="true" adaptive="true" pos="158, 76,0,0" width="210" height="145" >
</DuilibHDCUI4Gif>
*.cpp
CControlUI* CHomePage::CreateControl(LPCTSTR pstrClass)
{
......
if (_tcsicmp(pstrClass, DuilibHDCUI4Gif_Name) == 0)
{
CDuilibHDCUI4Gif*pUI = new CDuilibHDCUI4Gif(&m_PaintManager);
return pUI;
}
......
}
最后下载地址:http://download.youkuaiyun.com/detail/reloner12/8244375