EVC编程点滴-GIF动画显示类

eVC   2009-06-21 18:14   阅读96   评论0  
字号:    

http://blog.csdn.net/91program/archive/2007/12/06/1920524.aspx

EVC编程点滴-GIF动画显示类收藏
此功能在我这个项目中,主要是显示让用户等待的提示。如开机过程、待机界面调用一个系统应用的过程、还有就是操作大尺寸图片的过程。
刚开始是用自定义的一个窗体来提示用户的,功能也可以实现,但美观度不够。所以才花了一定时间,对网上这个类进行研究。最终成功应用于项目中。

这个类的实现,主要是参考网上一个名为CGif89a类的实现。
此类在EVC4工程中可以正常使用。

索引:
1) GIF显示类头文件
2) GIF显示类的实现
3) 调用CGIFShow类示例
    (1) 定义全局变量
    (2) 在窗体的WM_CREATE消息处理中初始化CGIFShow类的实例
    (3) GIF动画显示
    (4) 最后记得清理内存

=======================================
1) GIF显示类头文件
//////GIFShow.h////////
#ifndef GIFSHOW_H
#define GIFSHOW_H

#define DISPOSAL_NO 0
#define DISPOSAL_NOT 4
#define DISPOSAL_RESTBACK 8
#define DISPOSAL_RESTORE 12

typedef struct
{
    BYTE bit;
    WORD previouscode;
    WORD nextcode;
}GIFTABLE;


class CGIFShow
{
private:
    HDC     m_hWndHDC;
    bool    m_bPause;
    BOOL    m_bAutoStart;
    BOOL    m_bEmbed;
    BYTE    m_cCurentByte,m_cPackedField;
    UINT    m_uBitSize,m_uPrimaryBitSize;
    UINT    m_uRemain,m_uReadByte,m_uBlockSize;
    int     m_iWidth,m_iHeight;
    int     m_iTop,m_iLeft;
    int     m_iFinishCode,m_iResetCode;
    int     m_iPass,m_iRow;
    int     m_iWidth1;
    int     m_iBackgroundColor;
    int     m_iGifSize;
    int     m_x,m_y;
    int     m_iGlobalColorSize;
    int     m_iDisposalMethod;
    BOOL    m_bTransparentIndex;
    int     m_iTransparentIndex;
    int     m_iDelayTime;
    int     m_iTotalReadByte;
    int     m_iMaxByte;
    DWORD   m_dwSpeed;
    COLORREF m_TransparentColor;
    HDC     m_hDC;
    BYTE*   m_pcGlobalColorTable;
    BYTE*   m_pcBitmap;
    BYTE*   m_pcGif;
    BYTE*   m_pcGifTrack;
    BOOL    m_bGlass;
    volatile int m_EndRun;
    HBITMAP m_hRedrawBitmap;
    int     m_iGifWidth,m_iGifHeight;
    volatile BOOL   m_bLockBitmap;
    TCHAR   filename[_MAX_PATH];
    int     flag;
    BOOL    m_bRunMode;
    BOOL    m_bAutoSize1;
    int     m_nPosX;
    int     m_nPosY;

public:
    CGIFShow(HDC pWnd);
    ~CGIFShow();
    void Play();
    void Pause(bool status);///暂停运行
    void Stop();
    void SetPosition(int x,int y);
    BOOL Play1(void);
    BOOL Load(LPCTSTR filename);
    HBITMAP FirstImage(void);
    HBITMAP NextImage(void);
    HBITMAP TakeIt(void);
    HBITMAP DIBTohBitmap(HDC hDC,LPSTR   lpSrcDIB);

    void Output(BYTE bit)
    {
        int tmp;
        if(m_cPackedField&0x40)
        {
            if(m_x==m_iWidth)
            {
                m_x=0;
                if(m_iPass==1)m_iRow+=8;
                if(m_iPass==2)m_iRow+=8;
                if(m_iPass==3)m_iRow+=4;
                if(m_iPass==4)m_iRow+=2;
                if(m_iRow>=m_iHeight){m_iPass+=1;m_iRow=16>>m_iPass;}
            }
            tmp=m_iRow*m_iWidth1+m_x;
            m_pcBitmap[tmp]=bit;
            m_x++;
        }
        else
        {
            if(m_x==m_iWidth){m_x=0;m_y++;}
            tmp=m_y*m_iWidth1+m_x;
            m_x++;
        }
        if(tmp>m_iMaxByte)return;
        m_pcBitmap[tmp]=bit;
    }

    BYTE GetByte(void)
    {
        if(m_uReadByte>=m_uBlockSize)
        {
            m_uBlockSize=*m_pcGifTrack++;
            m_uReadByte=0;
            m_iTotalReadByte+=m_uBlockSize+1;
            if(m_iTotalReadByte>m_iGifSize){m_iTotalReadByte-=m_uBlockSize+1;return 0xFF;}
            if(m_uBlockSize==0){m_pcGifTrack--;m_iTotalReadByte--;return 0xFF;}
        }
        m_uReadByte++;
        return *m_pcGifTrack++;
    }

    WORD GetCode(void)
    {
        UINT tmp1;
        BYTE tmp;
        tmp=1;
        if(m_uRemain>=m_uBitSize)
        {
            tmp<<=m_uBitSize;
            tmp--;
            tmp1=m_cCurentByte&tmp;
            m_cCurentByte>>=m_uBitSize;
            m_uRemain-=m_uBitSize;
        }
        else
        {
            tmp<<=m_uRemain;
            tmp--;
            tmp1=m_cCurentByte;
            m_cCurentByte=GetByte();
            tmp=1;
            if(8>=(m_uBitSize-m_uRemain))
            {
                tmp<<=(m_uBitSize-m_uRemain);
                tmp--;
                tmp1=(((UINT)(m_cCurentByte&tmp))<<m_uRemain)+tmp1;
                m_cCurentByte>>=(m_uBitSize-m_uRemain);
                m_uRemain=8-(m_uBitSize-m_uRemain);
            }
            else
            {
                tmp1=(((UINT)(m_cCurentByte))<<m_uRemain)+tmp1;
                m_cCurentByte=GetByte();
                tmp<<=m_uBitSize-m_uRemain-8;
                tmp--;
                tmp1=(((UINT)(m_cCurentByte&tmp))<<(m_uRemain+8))+tmp1;
                m_cCurentByte>>=m_uBitSize-m_uRemain-8;
                m_uRemain=8-(m_uBitSize-m_uRemain-8);
            }
        }
        return tmp1;
    }

};
#endif

=======================================


#include "stdafx.h"
#include "GifShow.h"

DWORD WINAPI ThreadFunc(CGIFShow* ptr)
{
    ptr->Play1();
    return 0;
}

void CGIFShow::Play()
{
    HANDLE hThread;
    DWORD ThreadId;
    if(m_hWndHDC==0)return ;
    if(m_pcGif==0)return;
    if(m_EndRun==5)return;
    m_pcGifTrack=m_pcGif;
    m_iTotalReadByte=0;
    m_EndRun=5;
    hThread=CreateThread(NULL,0,(unsigned long(_stdcall*)(void*))ThreadFunc,this,0,&ThreadId);
    CloseHandle(hThread);
    return;
}

BOOL CGIFShow::Play1(void)
{
    HDC hDC,hMemDC,hMemDC1,hPauseMemDC;
    HBITMAP hOldBitmap,hOldBitmap1,hBitmap,hPreviousBitmap,hPauseBitmap;
    DWORD systimer1,systimer2,speed;
    BOOL PauseShow = FALSE;

    hDC = m_hWndHDC;
    hMemDC = ::CreateCompatibleDC(hDC);
    hMemDC1 = ::CreateCompatibleDC(hDC);
    hPauseMemDC = ::CreateCompatibleDC(hDC);
    m_hDC = hDC;
    hPreviousBitmap = 0;
    while(m_bLockBitmap)
    {
    }

    m_bLockBitmap = TRUE;
    if(m_hRedrawBitmap != 0)
    {
        DeleteObject(m_hRedrawBitmap);
    }
    m_hRedrawBitmap = ::CreateCompatibleBitmap(hDC,m_iGifWidth,m_iGifHeight);
    hOldBitmap1 = (HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap);
    hPauseBitmap = ::CreateCompatibleBitmap(hDC,m_iGifWidth,m_iGifHeight);
    SelectObject(hPauseMemDC,hPauseBitmap);
   
    ::BitBlt(hMemDC1,0,0,m_iGifWidth,m_iGifHeight,hDC,m_nPosX,m_nPosY,SRCCOPY);
    SelectObject(hMemDC1,hOldBitmap1);
    m_bLockBitmap = FALSE;
    m_iDisposalMethod = DISPOSAL_NOT;
    while(1 != m_EndRun)
    {
        systimer2=systimer1 = GetTickCount();
        while(m_bLockBitmap)
        {
        }
        m_bLockBitmap = TRUE;
        hOldBitmap1 = (HBITMAP)SelectObject(hMemDC1,m_hRedrawBitmap);
       
        switch(m_iDisposalMethod)
        {
        case DISPOSAL_NO:
            break;
        case DISPOSAL_NOT:
            break;
        case DISPOSAL_RESTBACK:
        case DISPOSAL_RESTORE:
            hOldBitmap = (HBITMAP)SelectObject(hMemDC,hPreviousBitmap);
            ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY);
            SelectObject(hMemDC,hOldBitmap);
            DeleteObject(hPreviousBitmap);
            hPreviousBitmap = 0;
            break;
        }
        m_iDisposalMethod = DISPOSAL_NO;
       
        if(!PauseShow)
        {
            hBitmap=NextImage();

            switch(m_iDisposalMethod)
            {
            case DISPOSAL_NO:
                break;
            case DISPOSAL_NOT:
                break;
            case DISPOSAL_RESTBACK:
            case DISPOSAL_RESTORE:
                hPreviousBitmap = ::CreateCompatibleBitmap(hDC,m_iWidth,m_iHeight);
                hOldBitmap = (HBITMAP)SelectObject(hMemDC,hPreviousBitmap);
                ::BitBlt(hMemDC,0,0,m_iWidth,m_iHeight,hMemDC1,m_iLeft,m_iTop,SRCCOPY);
                SelectObject(hMemDC,hOldBitmap);
                break;
            }
            hOldBitmap = (HBITMAP)SelectObject(hMemDC,hBitmap);
            if(m_bTransparentIndex)
            {
                HBITMAP    bmAndBack, bmAndObject;
                HBITMAP    bmBackOld, bmObjectOld;
                HDC        hdcBack, hdcObject;
                COLORREF cColor;

                hdcBack = ::CreateCompatibleDC(hDC);
                hdcObject = ::CreateCompatibleDC(hDC);
                bmAndBack = CreateBitmap(m_iWidth,m_iHeight,1,1,NULL);
                bmAndObject = CreateBitmap(m_iWidth,m_iHeight,1,1,NULL);
                bmBackOld = (HBITMAP)SelectObject(hdcBack,bmAndBack);
                bmObjectOld = (HBITMAP)SelectObject(hdcObject,bmAndObject);
                cColor = SetBkColor(hMemDC,m_TransparentColor);
                ::BitBlt(hdcObject,0,0,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY);
                SetBkColor(hMemDC,cColor);
                ::BitBlt(hdcBack,0,0,m_iWidth,m_iHeight,hdcObject,0,0,NOTSRCCOPY);
                ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hdcObject,0,0,SRCAND);
                ::BitBlt(hMemDC,0,0,m_iWidth,m_iHeight,hdcBack,0,0,SRCAND);
                ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCPAINT);
                DeleteObject(SelectObject(hdcBack,bmBackOld));
                DeleteObject(SelectObject(hdcObject,bmObjectOld));
                DeleteDC(hdcBack);
                DeleteDC(hdcObject);
            }
            else
            {
                ::BitBlt(hMemDC1,m_iLeft,m_iTop,m_iWidth,m_iHeight,hMemDC,0,0,SRCCOPY);
            }
            SelectObject(hMemDC,hOldBitmap);
            DeleteObject(hBitmap);
            ::BitBlt(hDC,m_nPosX,m_nPosY,m_iGifWidth,m_iGifHeight,hMemDC1,0,0,SRCCOPY);
            ::BitBlt(hPauseMemDC,0,0,m_iGifWidth,m_iGifHeight,hMemDC1,0,0,SRCCOPY);

        }
        else
        {
            ::BitBlt(hDC,m_nPosX,m_nPosY,m_iGifWidth,m_iGifHeight,hPauseMemDC,0,0,SRCCOPY);
        }

        SelectObject(hMemDC1,hOldBitmap1);
        m_bLockBitmap = FALSE;
        if(0 != m_iDelayTime)
            speed = m_iDelayTime * 10;
        else
            speed=m_dwSpeed;
        while((1 != m_EndRun)&&(speed > systimer2 - systimer1))
        {
            Sleep(10);
            systimer2 = GetTickCount();
        }
    PauseShow = m_bPause;
    }
    if(hPreviousBitmap != 0)
        DeleteObject(hPreviousBitmap);
    DeleteDC(hMemDC);
    DeleteDC(hMemDC1);
    //::ReleaseDC(hDC);
    m_EndRun = 2;
    return TRUE;
}


void CGIFShow::Stop()
{
    if(m_EndRun != 5)
        return;
    m_EndRun = 1;
    while(m_EndRun != 2)
    {
    }
    return;
}

CGIFShow::CGIFShow(HDC pWnd)
{
    m_hWndHDC=pWnd;
    m_bPause=FALSE;
    m_bAutoStart=TRUE;
    m_bAutoSize1=TRUE;
    m_bEmbed=FALSE;
    m_pcGlobalColorTable=0;
    m_pcGif=0;
    m_iGifSize=0;
    m_iGlobalColorSize=0;
    m_bTransparentIndex=FALSE;
    m_iDelayTime=0;
    m_EndRun=0;
    m_dwSpeed=50;
    m_hRedrawBitmap=0;
    m_bLockBitmap=FALSE;
    flag=0;
    m_nPosX=0;
    m_nPosY=0;
    wcscpy(filename,_T(""));
    m_bRunMode=1;
    m_bGlass=FALSE;
}

CGIFShow::~CGIFShow(void)
{
    Stop();
    if(m_hRedrawBitmap!=0)
        DeleteObject(m_hRedrawBitmap);
    if(m_pcGlobalColorTable!=NULL)
        delete[] m_pcGlobalColorTable;
    if(m_pcGif!=NULL)
        delete[] m_pcGif;
}

BOOL CGIFShow::Load(LPCTSTR filename)
{
    HANDLE hFile;
    DWORD size,size1,readbyte;
    BYTE temp[13];

    if(m_bEmbed)
        return FALSE;
   
    Stop();
    if(m_pcGlobalColorTable!=NULL)
        delete[] m_pcGlobalColorTable;
    if(m_pcGif!=NULL)
        delete[] m_pcGif;
    if(m_hRedrawBitmap!=0)
    {
        DeleteObject(m_hRedrawBitmap);
        m_hRedrawBitmap=0;
    }
    m_pcGlobalColorTable=m_pcGif=0;
    m_iTotalReadByte=0;
    m_iGifSize=m_iGlobalColorSize=0;
   
    hFile = CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(INVALID_HANDLE_VALUE==hFile)
        return FALSE;
    size=GetFileSize(hFile,&size1);
    if(size==0xFFFFFFFF)
    {
        CloseHandle(hFile);
        return FALSE;
    }
    ReadFile(hFile,temp,13,&readbyte,NULL);
    if((readbyte!=13)||((temp[0]!='G')||(temp[1]!='I')||
        (temp[2]!='F')||(temp[3]!='8')||((temp[4]!='7')&&
        (temp[4]!='9'))||(temp[5]!='a')))
    {
        CloseHandle(hFile);
        return FALSE;
    }
   
    m_iGifWidth=*(temp+6);
    m_iGifHeight=*(temp+8);
    m_iBackgroundColor=temp[11];
    if(temp[10]&0x80)
    {
        m_iGlobalColorSize=0x01<<((temp[10]&0x07)+1);
        m_pcGlobalColorTable=new BYTE[3*m_iGlobalColorSize];
        ReadFile(hFile,m_pcGlobalColorTable,3*m_iGlobalColorSize,&readbyte,NULL);
        if(readbyte!=(DWORD)3*m_iGlobalColorSize)
        {
            delete[] m_pcGlobalColorTable;
            m_pcGlobalColorTable=0;
            m_iGlobalColorSize=0;
            CloseHandle(hFile);
            return FALSE;
        }
    }

    m_iGifSize=size-3*m_iGlobalColorSize-12;
    m_pcGifTrack=m_pcGif=new BYTE[m_iGifSize];
    ReadFile(hFile,m_pcGif,m_iGifSize,&readbyte,NULL);
    CloseHandle(hFile);
    return TRUE;
}

HBITMAP CGIFShow::NextImage(void)
{
    if(m_pcGif==NULL)return 0;
   
label2: if(m_iTotalReadByte>m_iGifSize)
    {
        m_pcGifTrack=m_pcGif;
        m_iTotalReadByte=0;return 0;
    }
    m_iTotalReadByte++;
    switch(*m_pcGifTrack++)
    {
    case 0x2C:
        return TakeIt();
        break;
    case 0x21:
            BYTE cSize;
            m_iTotalReadByte++;
            switch(*m_pcGifTrack++)
            {
            case 0xF9:
                m_pcGifTrack++;//block size
                m_iDisposalMethod=(*m_pcGifTrack)&28;
                m_bTransparentIndex=(*m_pcGifTrack++)&1;

                m_iDelayTime=*m_pcGifTrack;
                m_pcGifTrack+=2;
                m_iTransparentIndex=*m_pcGifTrack++;
                m_iTotalReadByte+=5;
                break;
            case 0xFE:
                while((cSize=*m_pcGifTrack)!=0)
                {
                    m_pcGifTrack+=cSize+1;
                    m_iTotalReadByte+=cSize+1;
                    if(m_iTotalReadByte>m_iGifSize)
                        return 0;
                }
                break;
            case 0x01:
                m_pcGifTrack+=13;
                m_iTotalReadByte+=13;
                while((cSize=*m_pcGifTrack)!=0)
                {
                    m_pcGifTrack+=cSize+1;
                    m_iTotalReadByte+=cSize+1;
                    if(m_iTotalReadByte>m_iGifSize)
                        return 0;
                }
                break;
            case 0xFF:
                m_pcGifTrack+=12;
                m_iTotalReadByte+=12;
                while((cSize=*m_pcGifTrack)!=0)
                {
                    m_pcGifTrack+=cSize+1;
                    m_iTotalReadByte+=cSize+1;
                    if(m_iTotalReadByte>m_iGifSize)
                        return 0;
                }
                break;
            default:
                return FALSE;
            }
            m_pcGifTrack++;
            m_iTotalReadByte++;
            if(m_iTotalReadByte>m_iGifSize)
                return 0;
            goto label2;
            break;
    case 0x3B:
        m_pcGifTrack=m_pcGif;
        m_iTotalReadByte=0;
        goto label2;
    case 0:
        goto label2;
    default:
        return FALSE;
    }
}

HBITMAP CGIFShow::TakeIt(void)
{
    UINT uLocalColorTableSize;
    WORD code,oldcode,code1;
    int iFinishCode,iResetCode;
    int iPrimaryTableSize,iTableSize;
    BITMAPINFOHEADER *bitmapheader;
    BYTE *pcColorTable;
    BYTE *pcInfo;
    GIFTABLE *pcGifTable;
    HBITMAP hBitmap;
    m_iLeft=*m_pcGifTrack;
    m_pcGifTrack+=2;
    m_iTop=*m_pcGifTrack;
    m_pcGifTrack+=2;
    m_iWidth=*m_pcGifTrack;
    m_pcGifTrack+=2;
    m_iWidth1=((m_iWidth-1)|0x3)+1;
    m_iHeight=*m_pcGifTrack;
    m_pcGifTrack+=2;
    m_cPackedField=*m_pcGifTrack++;
    m_iTotalReadByte+=9;
    m_iMaxByte=m_iWidth1*m_iHeight;
    pcInfo=new BYTE[256*sizeof(RGBQUAD)+sizeof(BITMAPINFOHEADER)+m_iMaxByte+sizeof(GIFTABLE)*4096];
   
    bitmapheader=(BITMAPINFOHEADER*)pcInfo;
    pcColorTable=pcInfo+sizeof(BITMAPINFOHEADER);
    m_pcBitmap=pcColorTable+256*sizeof(RGBQUAD);
    pcGifTable=(GIFTABLE*)(m_pcBitmap+m_iMaxByte);
    for(int i=0;i<4096;i++)
        pcGifTable[i].previouscode=pcGifTable[i].nextcode=0;
    bitmapheader->biSize=sizeof(BITMAPINFOHEADER);
    bitmapheader->biWidth=m_iWidth;
    bitmapheader->biHeight=-m_iHeight;
    bitmapheader->biPlanes=1;
    bitmapheader->biBitCount=8;
    bitmapheader->biCompression=BI_RGB;
    bitmapheader->biSizeImage=0;
    bitmapheader->biXPelsPerMeter=0;
    bitmapheader->biYPelsPerMeter=0;
    bitmapheader->biClrUsed=256;
    bitmapheader->biClrImportant=256;

    if(m_cPackedField&0x80)
    {
        uLocalColorTableSize=1;
        uLocalColorTableSize<<=(m_cPackedField&7)+1;
        if(m_bTransparentIndex)
        {
            m_TransparentColor=RGB(m_pcGifTrack[m_iTransparentIndex*3],m_pcGifTrack[m_iTransparentIndex*3+1],m_pcGifTrack[m_iTransparentIndex*3+2]);
        }
        m_iTotalReadByte+=uLocalColorTableSize*3;
        for(UINT i=0;i<uLocalColorTableSize;i++)
        {
            pcColorTable[2]=*m_pcGifTrack++;
            pcColorTable[1]=*m_pcGifTrack++;
            pcColorTable[0]=*m_pcGifTrack++;
            pcColorTable[3]=0;
            pcColorTable+=4;
        }

    }
    else
    {
        BYTE *pcGlobalColor=m_pcGlobalColorTable;
        if(m_bTransparentIndex)
        {
            m_TransparentColor=RGB(pcGlobalColor[m_iTransparentIndex*3],pcGlobalColor[m_iTransparentIndex*3+1],pcGlobalColor[m_iTransparentIndex*3+2]);
        }
        for(int i=0;i<m_iGlobalColorSize;i++)
        {
            pcColorTable[2]=*pcGlobalColor++;
            pcColorTable[1]=*pcGlobalColor++;
            pcColorTable[0]=*pcGlobalColor++;
            pcColorTable[3]=0;
            pcColorTable+=4;
        }
    }
    m_uPrimaryBitSize=m_uBitSize=(*m_pcGifTrack++);
    m_iTotalReadByte++;
    iPrimaryTableSize=iTableSize=(1<<m_uBitSize)+2;
    iFinishCode=iTableSize-1;
    iResetCode=iFinishCode-1;

    m_uPrimaryBitSize++;
    m_uBitSize++;
    m_uRemain=0;
    m_cCurentByte=0;
    m_uBlockSize=0;
    m_uReadByte=1;
    m_x=m_y=0;
    m_iPass=1;
    m_iRow=0;
    while((code=GetCode())!=iFinishCode)
    {
        if(code==iResetCode)
        {
            m_uBitSize=m_uPrimaryBitSize;
            iTableSize=iPrimaryTableSize;
            oldcode=GetCode();
            if(oldcode>iTableSize)
            {
                delete[] pcInfo;
                return 0;
            }
            Output((BYTE)oldcode);
            continue;
        }
        if(code<iTableSize) //<code> exist in the string pcGifTable
        {
            code1=code;
            WORD code2=0;
            while(code1>=iPrimaryTableSize)
            {
                pcGifTable[code1].nextcode=code2;
                code2=code1;
                code1=pcGifTable[code1].previouscode;
                if(code1>=code2)
                {
                    delete[] pcInfo;
                    return 0;
                }
            }
            Output((BYTE)code1);
            while(code2!=0)
            {
                Output(pcGifTable[code2].bit);
                code2=pcGifTable[code2].nextcode;
            }
            pcGifTable[iTableSize].bit=(BYTE)code1;
            pcGifTable[iTableSize].previouscode=oldcode;
            iTableSize++;
            if(iTableSize==(0x0001<<m_uBitSize))
                m_uBitSize++;
            if(m_uBitSize>12)
                m_uBitSize=12;
            oldcode=code;
        }
        else
        {
            code1=oldcode;
            WORD code2=0;
            while(code1>=iPrimaryTableSize)
            {
                pcGifTable[code1].nextcode=code2;
                code2=code1;
                code1=pcGifTable[code1].previouscode;
                if(code1>=code2)
                {
                    delete[] pcInfo;
                    return 0;
                }
            }
            Output((BYTE)code1);
            while(code2!=0)
            {
                Output(pcGifTable[code2].bit);
                code2=pcGifTable[code2].nextcode;
            }
            Output((BYTE)code1);
            pcGifTable[iTableSize].bit=(BYTE)code1;
            pcGifTable[iTableSize].previouscode=oldcode;
            iTableSize++;
            if(iTableSize==(0x0001<<m_uBitSize))
                m_uBitSize++;
            if(m_uBitSize>12)
                m_uBitSize=12;
            oldcode=code;
        }
    }

    hBitmap = DIBTohBitmap(m_hDC,(LPSTR)pcInfo);
    m_pcGifTrack++;
    m_iTotalReadByte++;
    delete[] pcInfo;
    return hBitmap;
}

void CGIFShow::SetPosition(int x,int y)
{
    m_nPosX=x;
    m_nPosY=y;
}

void CGIFShow::Pause(bool status)
{
    m_bPause=status;
}
HBITMAP CGIFShow::DIBTohBitmap(HDC hDC,LPSTR   lpSrcDIB)
 {
      HBITMAP   hBitmap   =   NULL;
      HBITMAP   hOldBmp   =   NULL;
      HDC   hTmpDC   =   NULL;
      BITMAPINFOHEADER* bitmapheader = (BITMAPINFOHEADER*)lpSrcDIB;
      hBitmap = CreateCompatibleBitmap(hDC,bitmapheader->biWidth,
          -(bitmapheader->biHeight));
      hTmpDC=CreateCompatibleDC(hDC);
      hOldBmp=(HBITMAP)SelectObject(hTmpDC,hBitmap);

      StretchDIBits(hTmpDC,0,0,bitmapheader->biWidth,
          -bitmapheader->biHeight,0,0,bitmapheader->biWidth,
          -bitmapheader->biHeight,lpSrcDIB+40 + 256*sizeof(RGBQUAD),(BITMAPINFO*)lpSrcDIB,
          DIB_RGB_COLORS,SRCCOPY);

      SelectObject(hTmpDC,hOldBmp);
      DeleteDC(hTmpDC);
      return   hBitmap;
 }

=======================================

3) 调用CGIFShow类示例
    (1) 定义全局变量
    CGIFShow *pGIFInst;
   
    (2) 在窗体的WM_CREATE消息处理中初始化CGIFShow类的实例
    pGIFInst = new CGIFShow(GetDC(hWnd));
    注: CGIFShow 类需要显示在类似于窗体这样(应该说是具有画布属性)的句柄上。
        在第一次使用CGIFShow类时,我想显示在listview上,但是没有成功
   
    (3) GIF动画显示
    if(pGIFInst->Load(TEXT("waiting.gif")))
    {
        RECT rcClient;
        GetClientRect(hWnd, &rcClient);
      
        pGIFInst->SetPosition(96,130);
        pGIFInst->Play();
    }
    /*需要等待处理的调用代码*/
    pGIFInst->Stop();
   
    (4) 最后记得清理内存
    if(NULL != pGIFInst)
        delete pGIFInst;
    

发表于 @ 2007年12月06日 12:50:00|评论(34)

新一篇: EVC编程点滴-WM_TIMER冲突处理与精度 | 旧一篇: EVC编程点滴(概述)-注册表操作类seer_lz 发表于2008年4月11日 14:26:28  IP:举报
你好!我试着用你的这个CGIFShow类,添加到我的一个EVC工程里,并用EVC自带的模拟器运行,可是没有图片显示啊?但是load gif文件成功了我是直接显示在我的对话框上的某个区域。不知道是什么原因???91program 发表于2008年4月13日 14:09:22  IP:举报
LS是如何调用的?
这个类,我已经用过很多次了,应该不会有问题。

还有说说你所用的SDK吧,嵌入式的东东环境不一样,可能会需要修改才能运行、或者根本运行不了。seer_lz 发表于2008年4月14日 9:18:38  IP:举报
我暂时只用在了EVC自带的模拟器上,用的是STANDARDSDK。
另外想问下:你这个类在目标机上可以实现gif动态的效果吗?我是指纯粹的用来浏览图片时。91program 发表于2008年4月15日 18:31:21  IP:举报
可以实现GIF动画lby108 发表于2008年5月9日 14:19:04  IP:举报
谢谢楼主提供。我用了你改过的类,发现有一些BUG,在使用长或宽大于255像素的GIF时。后经检查,后来发现是因为LOAD函数中的XXX=*temp这样的赋值不正确,请你再查查看。。。lby108 发表于2008年5月9日 14:19:35  IP:举报
我的邮箱是lby108@sohu.com,欢迎交流。。。DonkeyWang 发表于2008年6月13日 11:18:02  IP:举报
lby108 发表于2008-05-09 14:19:03 IP: 125.33.151.*
谢谢楼主提供。我用了你改过的类,发现有一些BUG,在使用长或宽大于255像素的GIF时。后经检查,后来发现是因为LOAD函数中的XXX=*temp这样的赋值不正确,请你再查查看。。。

这位朋友说的没错,存在这么一些BUGzhuxianjun1 发表于2008年10月17日 16:43:36  IP:举报
我的也显示不了啊!!!!!zhuxianjun1 发表于2008年10月17日 16:47:07  IP:举报
怎么联系你呢?????
我的邮箱是:lmzhu79@tom.com
能给我一份代码?谢谢!!!!!!!!!!!!!!91program 发表于2008年10月21日 21:02:06  IP:举报
到我的CSDN共享资源中看看吧,有一个完整的工程可以下载。xumercury 发表于2008年10月24日 8:36:00  IP:举报
mark。經典的mark下lc402431247 发表于2008年11月11日 17:43:56  IP:举报
我用的是vs2005 用了楼主的代码,编译错误,但是就是显示不了gif图片.
麻烦楼主有时间在vs2005下运行下,谢谢.lc402431247 发表于2008年11月11日 17:45:08  IP:举报
噢.是编译无错误,上面少个字.lc402431247 发表于2008年11月11日 17:45:16  IP:举报
噢.是编译无错误,上面少个字.lc402431247 发表于2008年11月11日 17:46:26  IP:举报
编译无错误.lc402431247 发表于2008年11月11日 17:47:07  IP:举报
网速有点卡,提交了多次.lc402431247 发表于2008年11月11日 17:47:55  IP:举报
#91program 发表于2008-10-21 21:02:05 IP: 59.40.200.*
到我的CSDN共享资源中看看吧,有一个完整的工程可以下载。
-----------------------
没看见有完整的显示gif的工程.91program 发表于2008年11月11日 18:17:02  IP:举报
最近比较忙,且我一直用EVC4,虽然有安装VS2005,但不一定有时间试。看看吧!RainbowSu 发表于2008年11月29日 10:41:27  IP:举报
借鉴了一下, 发现主要问题是打不开文件..

hFile为无效句柄..RainbowSu 发表于2008年11月29日 14:37:10  IP:举报
呼..能用啦..原来是我在模拟器那边没有把文件部署好..

tokens 发表于2008年12月20日 16:32:14  IP:举报
lc402431247兄弟,2005可以用这个gif类,我已用上.
刚开始的时候,也是显示不了,看了你的留言,我以为是2005有问题,就移到evc4上,还是显示不了.然后一行行的跟踪,发现,如CreateCompatibleBitmap(hDC,...)返回的就是0,真是奇怪,然后一行行的分析,后来发现是hDC,被我提前release了(调play()后).日,看来好的习惯有时也害人,我宝贵的3小时.fan227 发表于2009年2月14日 10:09:24  IP:举报
试用了哈,不知道为何,pGIFInst->Load中的CreateFile返回的hFile为无效句柄, 路径名传的是TEXT("xxxxxx.gif"))),xxxxxx.gif放在exe目录下,应该没有问题,不知为何始终不行,楼主有没有DEMO啊,借鉴哈,或者贴部分看看!先谢了fan227 发表于2009年2月14日 10:09:27  IP:举报
试用了哈,不知道为何,pGIFInst->Load中的CreateFile返回的hFile为无效句柄, 路径名传的是TEXT("xxxxxx.gif"))),xxxxxx.gif放在exe目录下,应该没有问题,不知为何始终不行,楼主有没有DEMO啊,借鉴哈,或者贴部分看看!先谢了fan227 发表于2009年2月14日 10:10:11  IP:举报
试用了哈,不知道为何,pGIFInst->Load中的CreateFile返回的hFile为无效句柄, 路径名传的是TEXT("xxxxxx.gif"))),xxxxxx.gif放在exe目录下,应该没有问题,不知为何始终不行,楼主有没有DEMO啊,借鉴哈,或者贴部分看看!先谢了fan227 发表于2009年2月14日 10:11:16  IP:举报
网络的问题,所以提交了多次91program 发表于2009年2月14日 11:30:48  IP:举报
必须使用全路径,和EXE放在一起是不可行的。
因为CE系统,没有工作路径这个概念。91program 发表于2009年2月14日 11:33:51  IP:举报
当然如果一定要将GIF文件和EXE放在一起,可以使用GetModuleFileName()来得到EXE的路径,然后构建一个GIF的全路径,用做参数也可以。91program 发表于2009年2月14日 11:34:43  IP:举报
当然如果一定要将GIF文件和EXE放在一起,可以使用GetModuleFileName()来得到EXE的路径,然后构建一个GIF的全路径,用做参数也可以。fan227 发表于2009年2月14日 15:23:49  IP:举报
弄来弄去,还是路径的问题,我把GIF拷贝到我的CE系统上是可以的,但是我想把GIF作为RES资源,编译之后希望是EXE的一部分,不知道行不行,行的话该如何设置路径,该怎么做?
不知道有没有描述清楚,还是很感谢91program的及时答复。91program 发表于2009年2月16日 18:30:40  IP:举报
GIF动画做为资源,我没有试过hsyouxishe 发表于2009年3月6日 16:15:03  IP:举报
在wince6.0上测试通过可以显示gif,采用VS2005,但是貌似有的代码有内存泄露哦,
if (NULL != hPauseBitmap)
DeleteObject(hPauseBitmap);
hPauseBitmap = NULL;
DeleteDC(hPauseMemDC);
这个没有释放资源吧!
还有就是为什么对应背景透明的gif,背景显示的时候却是黑色的 透明不起来了!!

daifeijin 发表于2009年4月16日 9:57:17  IP:举报
û??????????????gif??????????????????daifeijin2008@163.com.?????????EVC?У???????JIF???????????????????????JIF??????????daifeijin 发表于2009年6月4日 11:58:04  IP:举报
GIF动画做为资源,我我改过,没有问题。可以用的。daifeijin 发表于2009年6月4日 12:02:48  IP:举报
用这个类的时候,感觉有的时候JIF图片和周围透明部分过度好像有问题。楼主能不能看一下?

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/91program/archive/2007/12/06/1920524.aspx

评论(?)
阅读(?)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
网易公司版权所有 ©1997-2009