这是我的代码:
void CPicViewView::OnDraw(CDC* pDC)
{
CPicViewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return; // TODO: 在此处为本机数据添加绘制代码


IPicture *pPic; 
IStream *pStm;  CFileStatus fstatus; 
CFile file; 
LONG cb;  if (file.Open("E:/xinwei/娱乐/picture/7caicg001.gif",CFile::modeRead)&&file.GetStatus("E:/xinwei/娱乐/picture/7caicg001.gif", 
fstatus)&& 
((cb = fstatus.m_size) != -1)) 

HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb); 
LPVOID pvData = NULL; 
if (hGlobal != NULL) 

if ((pvData = GlobalLock(hGlobal)) != NULL) 

file.Read(pvData, cb); 
GlobalUnlock(hGlobal); 
CreateStreamOnHGlobal(hGlobal, TRUE, &pStm);  if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID* 
)&pPic))) 

OLE_XSIZE_HIMETRIC hmWidth; 
OLE_YSIZE_HIMETRIC hmHeight;  pPic->get_Width(&hmWidth); 
pPic->get_Height(&hmHeight);  double fX,fY; 
fX = (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HORZSIZE)*100.0);  

fY = (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(VERTSIZE)*100.0); 
 
if(FAILED(pPic->Render(*pDC,10,10,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL))) 
 
AfxMessageBox("Failed To Render The picture!"); 
pPic->Release(); 

else 
AfxMessageBox("Error Loading Picture From Stream!"); 



else 
AfxMessageBox("Can't Open Image File!"); 
}

解决方案 »

  1.   

    http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp  
    http://www.codeproject.com/bitmap/pictureex.asp
      

  2.   

    我看了他的那个解说,那个需要什么CPictureCtrl 类,还要将其头文件包涵到工程中,这个类不是MFC中就有的吧?有没有其它一些办法呢?
      

  3.   

    MFC,包括像GDI+库都不支持动态gif的播放。要用VC显式动态的Gif,你就得一帧一帧地读,一帧一帧地画。上面这两个库都是做的类似的包装。
      

  4.   

    主要是有桢GDI+中GIF图片的显示一、GIF格式介绍
    1.概述  GIF(Graphics Interchange Format,图形交换格式)文件是由 CompuServe公司开发的图形文件格式,版权所有,任何商业目的使用均须 CompuServe公司授权。
      GIF图象是基于颜色列表的(存储的数据是该点的颜色对应于颜色列表的索引值),最多只支持8位(256色)。GIF文件内部分成许多存储块, 用来存储多幅图象或者是决定图象表现行为的控制块, 用以实现动画和交互式应用。GIF文件还通过LZW压缩算法压缩图象数据来减少图象尺寸。2.GIF文件存储结构  GIF文件内部是按块划分的,包括控制块( Control Block )和数据块(Data Sub-blocks)两种。控制块是控制数据块行为的,根据不同的控制块包含一些不同的控制参数; 数据块只包含一些8-bit的字符流,由它前面的控制块来决定它的功能,每个数据块大小从0到255个字节, 数据块的第一个字节指出这个数据块大小(字节数), 计算数据块的大小时不包括这个字节,所以一个空的数据块有一个字节,那就是数据块的大小0x00。 下表是一个数据块的结构:BYTE 7 6 5 4 3 2 1 0 BIT 
    0 块大小
     Block Size - 块大小,不包括这个这个字节(不计算块大小自身) 
    1  Data Values - 块数据,8-bit的字符串 
    2  
    ...  
    254  
    255    一个GIF文件的结构可分为文件头(File Header)、GIF数据流(GIF Data Stream)和文件终结器(Trailer)三个部分。文件头包含GIF文件署名(Signature)和版本号(Version);GIF数据流由控制标识符、图象块(Image Block)和其他的一些扩展块组成;文件终结器只有一个值为0x3B的字符('';'')表示文件结束。下表显示了一个GIF文件的组成结构: GIF署名 文件头  
     版本号 
     逻辑屏幕标识符 GIF数据流  
     全局颜色列表  
     ...  
     图象标识符 图象块                               
     图象局部颜色列表图 
                                基于颜色列表的图象数据  
     
     ...  
     GIF结尾 文件结尾    下面就具体介绍各个部分:文件头部分(Header)GIF署名(Signature)和版本号(Version)GIF署名用来确认一个文件是否是GIF格式的文件,这一部分由三个字符组成:"GIF";文件版本号也是由三个字节组成,可以为"87a"或"89a".具体描述见下表:BYTE 7 6 5 4 3 2 1 0 BIT 
    1 ''G'' GIF文件标识 
    2 ''I'' 
    3 ''F'' 
    4 ''8'' GIF文件版本号:87a - 1987年5月
            89a - 1989年7月 
    5 ''7''或''9'' 
    6 ''a'' GIF数据流部分(GIF Data Stream)逻辑屏幕标识符(Logical Screen Descriptor)这一部分由7个字节组成,定义了GIF图象的大小(Logical Screen Width & Height)、颜色深度(Color Bits)、背景色(Blackground Color Index)以及有无全局颜色列表(Global Color Table)和颜色列表的索引数(Index Count),具体描述见下表:BYTE 7 6 5 4 3 2 1 0 BIT  
    1 逻辑屏幕宽度 像素数,定义GIF图象的宽度 

    3 逻辑屏幕高度 像素数,定义GIF图象的高度 

    5 m cr s pixel 具体描述见下... 
    6 背景色 背景颜色(在全局颜色列表中的索引,如果没有全局颜色列表,该值没有意义) 
    7 像素宽高比 像素宽高比(Pixel Aspect Radio) m - 全局颜色列表标志(Global Color Table Flag),当置位时表示有全局颜色列表,pixel值有意义.
    cr - 颜色深度(Color ResoluTion),cr+1确定图象的颜色深度.
    s - 分类标志(Sort Flag),如果置位表示全局颜色列表分类排列.
    pixel - 全局颜色列表大小,pixel+1确定颜色列表的索引数(2的pixel+1次方).全局颜色列表(Global Color Table)全局颜色列表必须紧跟在逻辑屏幕标识符后面,每个颜色列表索引条目由三个字节组成,按R、G、B的顺序排列。BYTE 7 6 5 4 3 2 1 0 BIT 
    1 索引1的红色值  
    2 索引1的绿色值  
    3 索引1的蓝色值  
    4 索引2的红色值  
    5 索引2的绿色值  
    6 索引2的蓝色值  
    7 ...                              图象标识符(Image Descriptor)
    ~~~~~~~~~~~~~~~~~~~~~~~~~
    一个GIF文件内可以包含多幅图象,一幅图象结束之后紧接着下是一幅图象的标识符,图象标识符以0x2C('','')字符开始, 定义紧接着它的图象的性质,包括图象相对于逻辑屏幕边界的偏移量、图象大小以及有无局部颜色列表和颜色列表大小, 由10个字节组成:BYTE 7 6 5 4 3 2 1 0 BIT  
    1 0 0 1 0 1 1 0 0 图象标识符开始,固定值为'','' 
    2 X方向偏移量 必须限定在逻辑屏幕尺寸范围内 

    4 Y方向偏移量 

    6 图象宽度 

    8 图象高度 

    10 m i s r pixel m - 局部颜色列表标志(Local Color Table Flag) 
           置位时标识紧接在图象标识符之后有一个局部颜色列表,供紧跟在它之后的一幅图象使用;值否时使用全局颜色列表, 忽略pixel值。
    i - 交织标志(Interlace Flag),置位时图象数据使用交织方式排列 (详细描述...),否则使用顺序排列。
    s - 分类标志(Sort Flag),如果置位表示紧跟着的局部颜色列表分类排列.
    r - 保留,必须初始化为0.
    pixel - 局部颜色列表大小(Size of Local Color Table),pixel+1就为颜色列表的位数 局部颜色列表(Local Color Table)如果上面的局部颜色列表标志置位的话,则需要在这里(紧跟在图象标识符之后)定义一个局部颜色列表以供紧接着它的图象使用,注 意使用前应线保存原来的颜色列表,使用结束之后回复原来保存的全局颜色列表。如果一个GIF文件即没有提供全局颜色列表,也没有提供局部颜色列表, 可以自己创建一个颜色列表,或使用系统的颜色列表。局部颜色列表的排列方式和全局颜色列表一样:RGBRGB......基于颜色列表的图象数据(Table-Based Image Data)由两部分组成:LZW编码长度(LZW Minimum Code Size)和图象数据(Image Data)。BYTE 7 6 5 4 3 2 1 0 BIT 
    1 LZW编码长度 LZW编码初始码表大小的位数,详细描述见LZW编码... 
     
     
     
    ...
     图象数据,由一个或几个数据块(Data Sub-blocks)组成 数据块
     ...
     GIF图象数据使用了LZW压缩算法(详细介绍请看后面的『LZW算法和GIF数据压缩』),大大减小了图象数据的大小。图象数据在压缩前有两种排列格式:连续的和交织的(由图象标识符的交织标志控制)。连续方式按从左到右、从上到下的顺序排列图象的光栅数据;交织图象按下面的方法处理光栅数据:创建四个通道(pass)保存数据,每个通道提取不同行的数据:
    第一通道(Pass 1)提取从第0行开始每隔8行的数据;
    第二通道(Pass 2)提取从第4行开始每隔8行的数据;
    第三通道(Pass 3)提取从第2行开始每隔4行的数据;
    第四通道(Pass 4)提取从第1行开始每隔2行的数据;下面的例子演示了提取交织图象数据的顺序:行  通道1   通道2   通道3   通道4   
    0  -------------------------------------------------------- 1     
    1 --------------------------------------------------------    4  
    2  --------------------------------------------------------   3   
    3  --------------------------------------------------------    4  
    4  --------------------------------------------------------  2    
    5  --------------------------------------------------------    4  
    6  --------------------------------------------------------   3   
    7  --------------------------------------------------------    4  
    8  -------------------------------------------------------- 1     
    9  --------------------------------------------------------    4  
    10 --------------------------------------------------------   3   
    11 --------------------------------------------------------    4  
    12 --------------------------------------------------------  2    
    13 --------------------------------------------------------    4  
    14 --------------------------------------------------------   3   
    15 --------------------------------------------------------    4  
    16 -------------------------------------------------------- 1     
    17 --------------------------------------------------------    4  
    18 --------------------------------------------------------   3   
    19 --------------------------------------------------------    4  
    20 --------------------------------------------------------  2    
      

  5.   

    二、在GDI+中绘制GIFGDI+中绘制一个图片的代码如下: 
          void CMyWnd::OnPaint()
          {
           CPaintDC dc(this);
           Graphics graphics(&dc); // Create a GDI+ graphics object
          
           Image image(L"Test.Gif"); // Construct an image
           graphics.DrawImage(&image, 0, 0, image.GetWidth(), image.GetHeight());
          }
          
    Gif分为两种,一种是静态的,对于这种格式的Gif,在GDI+中无需采用任何方法就能够直接显示(上面的代码就属于这种情况)。另一种是动态的, 这种文件能够显示简单的动画。动态的实际上由多幅静态的组成,在显示Gif时,每幅图片按照一定的时间间隔依次进行显示,从而实现了动画效果。 
    我把GIF封装成了一个类ImageEx,这个类继承了GDI+中的Image类。我们首先要做的工作是判断GIF是动态的还是静态的。 
    bool ImageEx::TestForAnimatedGIF()
    {
            UINT count = 0;
            count = GetFrameDimensionsCount();
            GUID* pDimensionIDs = new GUID[count];
           
            // 得到子帧的对象列表
            GetFrameDimensionsList(pDimensionIDs, count);
           
         //获取总帧数
         m_nFrameCount = GetFrameCount(&pDimensionIDs[0]);
        
         // 假设图像具有属性条目 PropertyItemEquipMake.
         // 获取此条目的大小.
         int nSize = GetPropertyItemSize(PropertyTagFrameDelay);
        
         // 为属性条目分配空间.
         m_pPropertyItem = (PropertyItem*) malloc(nSize);
         GetPropertyItem(PropertyTagFrameDelay, nSize, m_pPropertyItem);
         delete pDimensionIDs;
         return m_nFrameCount > 1;
        
    }
    m_pPropertyItem->value 是一个长整形数组, 每个长整形代表每帧的延时。由于获取的属性不同,GetPropertyItem会获得不同大小的对象, 因此要由用户来获得的对象大小,开辟与删除 GetPropertyItem相关的内存。对象的大小是通过GetPropertyItemSize 获取的,其参数是你所感兴趣的属性条目。 一旦获取了帧的数量与延时,我们就可生成一个线程来调用 DrawFrameGIF()来显示。 
           bool ImageEx::DrawFrameGIF()
           {
           ::WaitForSingleObject(m_hPause, INFINITE);
           GUID pageGuid = FrameDimensionTime;
           long hmWidth = GetWidth();
           long hmHeight = GetHeight();
            HDC hDC = GetDC(m_hWnd);
            if (hDC)
            {
            Graphics graphics(hDC);
            graphics.DrawImage(this, m_rc.left, m_rc.top, hmWidth, hmHeight);
            ReleaseDC(m_hWnd, hDC);
            }
            SelectActiveFrame(&pageGuid, m_nFramePosition++); 
            if (m_nFramePosition == m_nFrameCount)
            m_nFramePosition = 0;
           
            long lPause = ((long*) m_pPropertyItem->value)[m_nFramePosition] * 10;
            DWORD dwErr = WaitForSingleObject(m_hExitEvent, lPause);
            return dwErr == WAIT_OBJECT_0;
            }
      

  6.   

    “类ImageEx”
    这个是他自己写的类,别人不明白也没有类的原型啊,
       看来VC要学的东西太多了!
      

  7.   

    回楼上,cpio(希望我的回复能带给您一点点帮助) ( )转帖的帖子中的例子“类ImageEx”实际上就是:
    http://www.codeproject.com/vcpp/gdiplus/imageexgdi.asp 只不过那篇文章的作者太没有道德了,把别人的成果据为己有。