作为GDI的升级版本的GDI+实在是个好东西,以前要播放GIF什么的,要引入其他辅助库,或者自己写GIF的读取过程。不过有了GDI+,这些事情都不必再操心了。

在GDI+的设计中,IMAGE本来就是分页、分帧的;可以说,GDI+的IMAGE的设计,本身就是考虑到了几乎目前所有主流图片格式的共性而设计出来的。废话不多说,贴上代码,看GDI+是如何播放GIF的

首先是GIF的载入:

void CGIFControl::Load(LPCTSTR sFileName)
{
    m_pImage = new Image(sFileName);
    UINT count = m_pImage->GetFrameDimensionsCount();
    m_pDimensionIDs =new GUID[count];
    m_pImage->GetFrameDimensionsList(m_pDimensionIDs, count);
    WCHAR strGuid[39];
    StringFromGUID2(m_pDimensionIDs[0], strGuid, 39);
    m_FrameCount = m_pImage->GetFrameCount(&m_pDimensionIDs[0]);

    //PropertyTagFrameDelay是GDI+中预定义的一个GIG属性ID值,表示标签帧数据的延迟时间
    UINT TotalBuffer = m_pImage->GetPropertyItemSize(PropertyTagFrameDelay);
    m_pItem = (PropertyItem*)malloc(TotalBuffer);
    m_pImage->GetPropertyItem(PropertyTagFrameDelay,TotalBuffer,m_pItem);
}

接着给出播放的代码,值得注意的是,播放我选择了使用WM_TIMER消息,而不是像有些(还比较主流)开源的GIF播放库那样,单独开一个线程来播放,主要是没必要开线程,系统复杂度还高一些(个人意见)。需要注意的一点就是,绘制GIF帧之前,需要用SelectActiveFrame把那个帧设置为当前绘制的帧。

void CGIFControl::OnTimer(UINT_PTR nIDEvent)
{
    KillTimer(nIDEvent);

    GUID Guid = FrameDimensionTime;
    m_pImage->SelectActiveFrame(&Guid,m_iCurrentFrame);

    SetTimer(1,((UINT*)m_pItem[0].value)[m_iCurrentFrame] * 10,NULL);

    m_iCurrentFrame = (++ m_iCurrentFrame) % m_FrameCount;
    Invalidate(FALSE);
}

 

绘制的代码不多说了,地球人都知道

Graphics g(lpDrawItemStruct->hDC);

            DrawBorder(g);
            CRect rcClient;
            GetClientRect(&rcClient);

            if(m_bBorderEnable)
            {
                rcClient.DeflateRect(m_iBorderLineWidth,m_iBorderLineWidth,m_iBorderLineWidth,m_iBorderLineWidth);
            }

            g.DrawImage(m_pImage,rcClient.left,rcClient.top,rcClient.Width(),rcClient.Height());

 

好了,就这么多。

posted on 2008-03-29 15:32 亨德列克 阅读(2657) 评论(2)  编辑 收藏 引用
Comments
  • # re: 使用GDI+来播放GIF[未登录]
    漂舟
    Posted @ 2008-03-31 08:56
    呵呵,最近我也在了解这个,
    确实是个好东西,
    我们程序员生产效率的提升,
    绝大多数得益于基础库的完善。  回复  更多评论   
  • # re: 使用GDI+来播放GIF
    Binary
    Posted @ 2008-12-02 11:10
    m_pDimensionIDs =new GUID[count];
    注意 delete啊  回复  更多评论   

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理