我的手机开发(九)——使用IImage组件播放GIF

   第九篇,看来世界上十全十美的事还真是很少。所以,从今天开始,回归基础,继续加油。工欲善其事,必先利其器。不抛弃,不放弃,加油,fighting,go on!

   COM组件,一个很有意思的东西,原来没有接触过,但是很感兴趣。精益求精,所以为了优化任务,就又用COM组件把项目从新修改了一遍,再次谢谢老师,感谢老师不厌其烦的指教,谢谢谢谢,很感谢。

   首先我们看一下什么是COM,网上资料很多,很详细。列举如下。

Question

什么是COM组件?

Answer:

COM组件是以WIN32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行代码组成。

COM组件是遵循COM规范编写的

COM组件是一些小的二进制可执行文件

COM组件可以给应用程序、操作系统以及其他组件提供服务

自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序

COM组件可以动态的插入或卸出应用

COM组件必须是动态链接的

COM组件必须隐藏(封装)其内部实现细节

COM组件必须将其实现的语言隐藏

COM组件必须以二进制的形式发布

COM组件必须可以在不妨碍已有用户的情况下被升级

COM组件可以透明的在网络上被重新分配位置

COM组件按照一种标准的方式来宣布它们的存在

Question

  组件不是……?

Answer:

COM组件不是一种计算机语言

COM组件不是DLL,只是利用DLL来给组件提供动态链接的能力

COM组件不是一个API函数集。

COM组件不是类

怎么样,COM很神奇吧。但是不用怕,其实COM用起来,就像是我们平常经常用的库函数,我们不必关心它是怎么实现的,只要按照使用说明去用就行了,当然要是想研究COM,设计COM,那就要好好思考了,COM这种优秀的编程思想。小弟才疏学浅,就不卖弄了。我只能先站在使用者的角度,讲讲COM怎么用。

   起先由于没有接触过COM,用起来很不顺手,总是跟COM较劲儿:这个解码信息在哪?位图呢?它怎么没有。。。?它怎么不是。。。?它怎么不用。。。?等等等等,心里老是想按照自己的想法去做,但是COM就是COM它不会因你而改变。你只能按照它的套路出牌。

   记得老师总是说让我看文档,看文档,其实我看了,但是总是按照自己的想法去解读COM,结果总是出错。下面我们看看IImage组件是怎么实现GIF循环播放的吧

第一步:创建文件流,注册COM组件

 1   
 2  IStream *   stream  =  CreateStreamByFileName(fileName);
 3 
 4     if  ( ! stream)                         
 5    {
 6      return   false ;
 7    }
 8 
 9 
10    hr  =  factory -> CreateImageDecoder(stream, DecoderInitFlagBuiltIn1st,  & decoder);
11     if  (FAILED(hr))
12 
13   
14 
15 
16    {
17      return   false ;
18    }

第二步:取得图片信息

 

 1  hr  =  decoder -> TerminateDecoder(); // 初始化decoder
 2    LARGE_INTEGER dlibMove  =  {  0 0  };
 3    hr  =  stream -> Seek( dlibMove, STREAM_SEEK_SET, NULL );
 4    hr  =  decoder -> InitDecoder(stream, DecoderInitFlagBuiltIn1st);
 5 
 6    decoder -> GetPropertyItemSize(PropertyTagFrameDelay,  & size); // 取得GIF中的延时间
 7    decoder -> GetPropertyItem(PropertyTagFrameDelay, size,  & pi);
 8    
 9    hr  =  decoder -> GetImageInfo( & ii); // 取得帧数信息
10    decoder -> GetFrameDimensionsCount( & count1);
11    decoder -> GetFrameDimensionsList( & guid, count1);
12    decoder -> GetFrameCount( & guid,  & count);

第三步:循环播放(Draw相应的位图)

 

 1  hr  =  decoder -> SelectActiveFrame( & guid, i);
 2        if  (FAILED(hr))
 3       {
 4         return   false ;
 5       }
 6 
 7       hr  =  factory -> CreateNewBitmap(ii.Width, ii.Height, PixelFormatDontCare,  & bmpimg);
 8        if  (FAILED(hr))
 9       {
10         return   false ;
11       }
12       bmpimg -> QueryInterface(IID_IImageSink, ( void ** ) & sink);
13 
14       hr  =  decoder -> BeginDecode(sink, NULL);
15        if  (FAILED(hr))
16       {
17         return   false ;
18       }
19 
20       hr  =  decoder -> Decode();
21        if  (FAILED(hr))
22       {
23         return   false ;
24       }
25       bmpimg -> QueryInterface(IID_IImage, ( void ** ) & image);
26 
27       ::BitBlt(tempDC,  0 0 , ii.Width, ii.Height, gif -> GetBkDC(),  0 0 , SRCCOPY);
28 
29       image -> Draw(tempDC,  & rect, NULL);
30       ::BitBlt(hdc,  0 0 , ii.Width, ii.Height, tempDC,  0 0 , SRCCOPY);
31 
32       decoder -> EndDecode(hr);
33        // 设置延时 
34       Sleep(( ( long * )pi.value )[i] * 10 );
35       image -> Release();
36       sink -> Release();
37       bmpimg -> Release();
38       image  =  NULL;
39       sink  =  NULL;
40       bmpimg  =  NULL;

第四步:释放资源(位图、内存、组件)

OK大功告成,利用组件很简单吧,只要按照说明,一步步地把各个职位(COM接口)安排好,这个COM公司就会帮我们运做,生产出我们想要的产品。

COM会用了。但是学无止境,老师说我直接开线程的方式写GIF播放还是很幼稚,老师让我好好思考一下Windows编程。

windows编程其核心就是消息机制。进而我们可以用消息来控制线程的运行。这样的话。。。。

还有windows中窗口的刷新都涉位图的绘制,所以在窗口刷新前,要将各种材料(需要显示的位图)准备好,然后再在指定的区域重绘。

这样windows开发在头脑中又清晰了许多。keep running.....bless everyone 

转载于:https://www.cnblogs.com/rubywang/archive/2009/03/14/1412108.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值