Duilib扩展—扩展GIF显示

在用duilib实际开发应用中,有时需要显示一些动态的图片,比如loading加载之类的。而duilib中负责对图片载入相关处理的stb_image.c对这块没有提供很好的支持,所以需要我们自行进行相关扩展。而对于动态图片效果,我们可以根据实际应用场景分两种:

一. loading加载

loading等待状态的图片效果,对于这类比较简单的情况,实际上不需要额外对duilib进行相关扩展。我们只需要将准备好几张一个loading图片在不同位置状态下的几张图片。然后设置Timer进行背景替换即可。

二. GIF动画图片

对于一些复杂一点的动画图片,如果用上述设置Timer替换的方式显然不太方便。这种情况下,我们就需要对duilib进行相关扩展。
动态gif简单的理解为:gif文件是由多张普通的bmp图片组成,显示第1张BMP,延时一段时间,显示第二张,延时一段时间,显示第3张...
stb_image.c中增加一个加载动态gif的函数 TGifInfo* gif_load_from_memory().

动态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.

使用时需要在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函数。


PS: 关注公众号,技术分享,学习交流 

你可能感兴趣的:(duilib,界面库)