第九篇,看来世界上十全十美的事还真是很少。所以,从今天开始,回归基础,继续加油。工欲善其事,必先利其器。不抛弃,不放弃,加油,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组件
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 }
第二步:取得图片信息
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相应的位图)
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
浙公网安备 33010602011771号