精华内容
下载资源
问答
  • COM组件书籍

    热门讨论 2008-07-17 11:09:31
    介绍COM组件书籍
  • COM组件

    热门讨论 2007-05-04 02:02:30
    学习COM 组件编程书籍
  • com组件方面的书籍

    千次阅读 2010-08-14 16:09:00
    com本质论(此书很类似另外一本讲c的书,《c标准和实现》,讲解深入了编译的层次,我喜欢) 深入解析ATL 潘爱民 COM技术原理 ...COM+组件服务技术内幕(CHM) com组件设计和应用 ATL模板库参考手册
    com本质论(此书很类似另外一本讲c的书,《c标准和实现》,讲解深入了编译的层次,我喜欢) 深入解析ATL 潘爱民 COM技术原理 完全剖析COM+基本架构 COM 技术内幕-微软组件对象模型 COM与COM+从入门到精通 com+编程指南 COM+组件服务技术内幕(CHM) com组件设计和应用 ATL模板库参考手册
    展开全文
  • 寻找joomla图书组件 有人知道joomla有没有类似图书组件 比如百度文库或者http://optoelectronics.liteon.com/en-global/Led/LED-Component/Detail/459 都可以 有人知道吗? 急
  • 工作中写WinForm程序经常会引用第三方的组件,包括引用Com组件,做了一个桌面程序需要展示PDF,看了些其它的开源组件对PDF的兼容性都不是很好,有些看着PDF是正常的但是复制出来的字有很多乱码。然后就直接引用了...

    1、WinForm引用Adobe PDF Reader  

    工作中写WinForm程序经常会引用第三方的组件,包括引用Com组件,做了一个桌面程序需要展示PDF,看了些其它的开源组件对PDF的兼容性都不是很好,有些看着PDF是正常的但是复制出来的字有很多乱码。然后就直接引用了adboe pdf reader来显示,测试了不同pdf兼容性算是不错的。那如何引用呢? 

    • 在工具栏选择项

    • 添加Com组件

    找到Adobe PDF Reader勾选,然后点击确定之后组件就被添加到工具箱里面了。

    • 使用Com组件

    新建一个窗体或者用户控件,将刚才添加的Adobe PDF Reader 组件拖入到窗体中就可以像winform控件一样操作该控件了。

    在该窗体类中生成了一个AxAcroPDFLib.AxAcroPDF的控件,进入该控件类可以看到控件类对外提供的方法,包括用于加载显示pdf的 LoadFile 方法,gotoFirstPage 等翻页的方法。
     

    而该控件有一个父类AxHost类,进入Axhost类有一个摘要:  

    包装 ActiveX 控件,并将它们作为功能完整的 Windows 窗体控件公开  

    对此我陷入了沉思,ActiveX控件到底是什么,com组件如何被使用,AxAxAcroPDFLib.AxAcroPDF类是如何生成的,Winform和Com如何互操作?于是我进行了一番资料查找和学习。

    2、ActiveX控件    

    ActiveX控件技术基于由COM,可连接对象,复合文档,属性页,OLE自动化,对象持久性以及系统提供的字体和图片对象组成的基础。
    控件本质上是一个COM对象,它公开IUnknown接口,客户端可以通过该对象获取指向其其他接口的指针。控件可以通过IClassFactory2和自我注册来支持许可。
    也就是说ActiveX控件是基于COM对象的,使用COM技术让不同语言编写的控件可以进行互相调用,而如何编写ActiveX控件呢,可以使用ATL 和 MFC,但是两个我都没使用过!并且没编写过,所以我就略过,只先了解其概念。既然它是基于COM,那接下来看看COM是什么东东。

     3、COM技术  

     Microsoft组件对象模型(COM)定义了一个二进制互操作性标准,用于创建在运行时进行交互的可重用软件库。您可以使用COM库,而无需将其编译到应用程序中。COM是许多Microsoft产品和技术(例如Windows Media Player和Windows Server)的基础。
    COM定义了适用于许多操作系统和硬件平台的二进制标准。对于网络计算,COM为在不同硬件平台上运行的对象之间的交互定义了标准的有线格式和协议。COM独立于实现语言,这意味着您可以使用其他编程语言(例如C ++和.NET Framework中的编程语言)创建COM库。
    COM规范提供了支持跨平台软件重用的所有基本概念:
    组件之间的函数调用的二进制标准。
    将功能强类型分组到接口中的规定。
    提供多态性,功能发现和对象生存期跟踪的基本接口。
    唯一标识组件及其接口的机制。
    组件加载器,可从部署中创建组件实例。
    COM具有多个部分,这些部分可以一起工作以创建由可重用组件构建的应用程序:
    一个主机系统提供了一个运行时环境符合的COM规范。
    定义要素合同的接口和实现接口的组件。
    为系统提供组件的服务器,以及使用组件提供的功能的客户端。
    一个注册表,用于跟踪组件在本地和远程主机上的部署位置。
    一个服务控制管理器,可以在本地和远程主机上找到组件,并将服务器连接到客户端。
    一种结构化的存储协议,它定义了如何导航主机文件系统上文件的内容。
    跨主机和平台启用代码重用对于COM至关重要。可重用的接口实现被称为组件,组件对象或COM对象。组件实现一个或多个COM接口。
    您可以通过设计库实现的接口来定义自定义COM库。图书馆的使用者可以发现和使用其功能,而无需了解图书馆的部署和实施细节。

    这是官方的定义,当然还有很多细节说明可以看看https://docs.microsoft.com/zh-cn/windows/win32/com/com-technical-overview 其中包括实现的定义和方式,对象和接口、接口实现、IUnknown接口等等。

    那是如何实现如何调用呢,引用一段有趣的概括性的描述:

    COM主要是一套给C/C++用的接口,当然为了微软的野心,它也被推广到了VB、Delphi以及其他一大堆奇奇怪怪的平台上。它主要为了使用dll发布基于interface的接口。我们知道dll的接口是为了C设计的,它导出的基本都是C的函数,从原理上来说,将dll加载到内存之后,会告诉你一组函数的地址,你自己call进去就可以调用相应的函数。
    但是对于C++来说这个事情就头疼了,现在假设你有一个类,我们知道使用一个类的第一步是创建这个类:new MyClass()。这里直接就出问题了,new方法通过编译器计算MyClass的大小来分配相应的内存空间,但是如果库升级了,相应的类可能会增加新的成员,大小就变了,那么使用旧的定义分配出来的空间就不能在新的库当中使用。
    要解决这问题,我们必须在dll当中导出一个CreateObject的方法,用来代替构造函数,然后返回一个接口。然而,接口的定义在不同版本当中也是有可能会变化的,为了兼容以前的版本同时也提供新功能,还需要让这个对象可以返回不同版本的接口。接口其实是一个只有纯虚函数的C++类,不过对它进行了一些改造来兼容C和其他一些编程语言。
    在这样改造之后,出问题的还有析构过程~MyClass()或者说delete myClass,因为同一个对象可能返回了很多个接口,有些接口还在被使用,如果其中一个被人delete了,其他接口都会出错,所以又引入了引用计数,来让许多人可以共享同一个对象。
    其实到此为止也并不算是很奇怪的技术,我们用C++有的时候也会使用Factory方法来代替构造函数实现某些特殊的多态,也会用引用计数等等。COM技术的奇怪地方在于微软实在是脑洞太大了,它们构造了一个操作系统级别的Factory,规定所有人的Interface都统一用UUID来标识,以后想要哪个Interface只要报出UUID来就行了。这样甚至连链接到特定的dll都省了。
    这就好比一个COM程序员,只要他在Windows平台上,调用别的库就只要首先翻一下魔导书,查到了一个用奇怪文字写的“Excel = {xxx-xxx-xxxx...}”的记号,然后它只要对着空中喊一声:“召唤,Excel!CoCreateInstance, {xxx-xxx-xxxx...}”
    然后呼的从魔法阵里面窜出来了一个怪物,它长什么样我们完全看不清,因为这时候它的类型是IUnknow,这是脑洞奇大无比的微软为所有接口设计的一个基类。我们需要进一步要求它变成我们能控制的接口形态,于是我们再喊下一条指令:
    “变身,Excel 2003形态!QueryInterface, {xxx-xxx-xxxx...}”
    QueryInterface使用的是另一个UUID,用来表示不同版本的接口。于是怪物就变成了我们需要的Excel 2003接口,虽然我们不知道它实际上是2003还是2007还是更高版本。
    等我们使唤完这只召唤兽,我们就会对它说“回去吧,召唤兽!Release!”但是它不一定听话,因为之前给它的命令也许还没有执行完,它会忠诚地等到执行完再回去,当然我们并不关心这些细节。(引用地址:https://www.zhihu.com/question/49433640)

    从这个概括理解,所有的COM类其实都继承了IUnknown,当我们拿到IUnknown接口后还需要转成我们需要使用的类型,而这个类型如果用强转可能会出错,但是微软认为,直接由用户来转型是不安全的需要唯一的一个标识符来确定一个类,那么这个标识符就是GUID。类ID就叫作CLSID,接口ID就叫作IID,还需要一个转型的函数叫QueryInterface。QueryInterface作为IUnknown中的一个纯虚函数,做的事情其实很简单,判断自己能不能转成某个GUID所指向的类而已。如果不可以,则返回E_NOTIMPL,可以的话返回S_OK,并将转换后的指针作为参数返回。
    COM组件并不需要名字,或者说不需要UUID,因为我们总是使用他里面的接口,而不是直接使用COM组件,所以接口也要UUID。说了这么多,COM架构这么复杂,肯定需要一个中间层,或者说摆渡人,这就是COM Library(一堆dll) + 注册表。A应用通知COM Library,并输入接口的UUID,由COM Library装入B应用的该组件对应的dll,并把接口指针返回给A应用,指针里指示的是一堆函数指针,由这些指针,可以调用到B应用里的函数功能。

     注:上面有时说的UUID,有时说的GUDI,UUID即是GUID值。

    4、Aximp.exe(Windows 窗体 ActiveX 控件导入程序)  

    有了上面的ActiveX控件和Com组件的介绍,我们再回到开始我们如何导入的ActiveX控件。
    ActiveX 控件导入程序将 ActiveX 控件的 COM 类型库中的类型定义转换为 Windows 窗体控件。
    Windows 窗体只能承载 Windows 窗体控件,即从 Control 派生的类。 Aximp.exe 生成可承载于 Windows 窗体上的 ActiveX 控件的包装器类。 这使你得以使用适用于其他 Windows 窗体控件的同一设计时支持和编程方法。
    若要承载 ActiveX 控件,必须生成从 AxHost 派生的包装器控件。 此包装器控件包含基础 ActiveX 控件的一个实例。 它知道如何与 ActiveX 控件通信,但它显示为 Windows 窗体控件。 这个生成的控件承载 ActiveX 控件并将其属性、方法和事件作为生成的控件的属性、方法和事件公开。  
    由此可见当我们再工具箱里面选择添加com组件后实际隐含执行了该导入程序,为我们生成了对应的AxAcroPDFLib.AxAcroPDF包装器控件。而AxAcroPDFLib则如同第三点中讲的那样就是COM Library。
     5、验证
    既然AxAcroPDFLib 是摆渡人(互操作程序集) 那么我们可以看到这个COM Library的引用

    有了互操作程序那么这个互操作程序必然是去调用COM组件,调用COM组件那么UUID呢?将这个程序集放到Dnspy反编译可以看到在ClsidAttribute标记有{ca8a9780-280d-11cf-a24d-444553540000},构造函数里面有UUID。

    然后我们打开注册表查询下对应的值和注册表的情况。

    6、总结  

    所以通过上面的概念了解和猜想验证,基本清楚了com的设计和想法,以及ActiveX控件的调用过程。

    1.  Activex控件时COM实现的一种方式。
    2.  Activex控件通过VS工具引用时调用了Aximp.exe 。
    3.  Aximp.exe程序生成了互操作程序集AxAcroPDFLib,同时生成可承载于 Windows 窗体上的 ActiveX 控件的从 AxHost 派生的包装器控件。
    4. 调用AxAcroPDF方法时通过com组件调用引用控件的功能。
       
    展开全文
  • 推荐几本个人读过的比较不错的COM组件相关的书籍,按我的阅读感受排名如下: 1,《Visual C++实践与提高-COMCOM+篇》    这本书我放在第一位,倒不是它有多么出色,但我却认为它是最适合新手的...
    推荐几本个人读过的比较不错的COM组件相关的书籍,按我的阅读感受排名如下: 
    

    1,《Visual C++实践与提高-COM和COM+篇》

     

          这本书我放在第一位,倒不是它有多么出色,但我却认为它是最适合新手的。它的内容基本都是抄袭下面潘爱民那本《COM原理与应用》的,但我推荐它有两点原因,首先,基本照搬潘那本书的原理性的东西,但加入了许多实例,比前者纯理论的书要易读些,对于新手更容易接受。其次,它的第二章实在是写的太出色,带你从c++一步步走向COM,引人入胜,让人叫绝,就冲这一章的内容,此书值矣。 

    2,《COM原理与应用》

     

          这本书的名气就不用多说了,看其作者就知道品质必有保障。IUnknown接口,引用计数,接口查询,类厂,COM库支持,COM的具体实现,包容和聚合等基础理论讲解得非常详细,当然第2部分讲述COM扩展我没有看,无法评价。除此以外,作者也在第5章举了些COM组件开发示例,在第12章专门讲述ActiveX的开发。 

    3,《COM技术内幕——微软组件对象模型》

     

         说实话,我感觉这本书的风格更像是本《故事会》,呵呵。。。,

    我总结了几个优点:1)适合入门。全书对com的讲解由浅入深,可以用循循善诱来形容。例子的由浅入深是本书最大的有优点,一个字“赞”。2)每章开头都用与技术无甚关系的例子作为引入,类比引入,比较有趣。结合COM原理和它的代码,很值得玩味。。。

    4,《深入解析ATL》

     

    我比较喜欢用ATL开发COM组件这种方式,模板类和多继承的使用比MFC那套让人舒服的多,再搭配上WTL就更好了。

    第2章讲解字符串,字符串向来是C++的一个痛处,混乱不堪,此章属必读。

    第3章讲ATL的一些智能类型,第8章更是让人叫绝,在ATL中像使用STL一样去使用集合和迭代器,很棒!

    5,《Creating XPCOM Components

     

          如果你想做跨平台的COM组件,Mozilla的XPCOM无疑是个好选择,firefox也是正当红,为其写扩展的人很多,而XPCOM正是其核心技术。

          这本书通过一个扩展实例的完整开发流程,很轻松就将你带入firefox扩展的开发者队伍中,即使你仅仅喜欢COM,那也没问题,两者基本思想都是一样的。

    作者:洞庭散人

    出处:http://phinecos.cnblogs.com/    

    本博客遵从 Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(1476) | 评论(0) | 转发(0) |
    0

    上一篇:十大C++经典教程

    下一篇:字体设置 OLLYDBG

    给主人留下些什么吧!~~
    评论热议
    展开全文
  • 与潘爱民 的 com组件原理与应用书籍配套的
  • com组件

    千次阅读 2011-08-30 11:18:33
     网上有很多关于com的文章,比较好的有杨老师文章(在vc知识库上有连载),还有一些经典的com书籍,这里不做过多介绍,从com编写直接开始,简单迅速的了解com; 一般com开发可以用ATL向导(这里vc6),当然如果你...

    引用本为说明出处:chinabinlang的专栏;(以下示例均在VC6上编译执行通过)

     

     

    一:COM的创建:

     网上有很多关于com的文章,比较好的有杨老师文章(在vc知识库上有连载),还有一些经典的com书籍,这里不做过多介绍,从com编写直接开始,简单迅速的了解com;

    一般com开发可以用ATL向导(这里vc6),当然如果你很牛,可以不用向导;

    开发步骤:ATL COM AppWizard -> Dynamic Link Library(DLL)   ->  Insert   ->  New ATL Object...   ->  Category Objects(选择 Simple Object)  -> next ->  Names属性框中写你的com对象名字, Attributes属性框,可以修改 Interface 下的为 Custom(也可以默认Dual)-> 确定;

    这样就添加了com对象了,如何先进接口的方法呢? 鼠标右键到接口上(像一个小勺子)选择 Add Method...,具体实现在类里面;

     

    用ATL创建com组件:
    1:通常通过添加 New ATL Object | Simple Object 添加com组件的一个对象;默认情况下,一个组件对象对应一个接口(一个dll可以添加多个Simple Object ,每个Simple Object 都是一个组件对象,通过CoCreateInstance创建同时创建一个接口),可以通过这种方式添加多个组件对象;
        可以在一个对象下添加多个接口类(com组件的接口就是外部看见的类)(就是QueryInterface到同一个组件下的多个不同接口类,如第2点所示);

    2:com中对象的可以包含多个接口,在ATL中,默认情况下,一个对象对应一个接口;
       可以通过鼠标右键到某个对象上 选择:Implement Interface,给这个对象添加新的接口,但是同名函数会被隐藏;
       注意:虽然都是同一个接口,但是,在不同对象下的具体函数内容要具体实现,如:
             Objectone对象添加 Objecttwo对象的接口Iobjtow,同时Iobjtow有objtowFun1函数,
             这时,Objectone 和 Objecttwo 都要具体实现objtowFun1函数,函数内容可以不同;

    3:调用Iobjtow接口,如果是想调用Objecttwo对象的实现,这样调用:
                       ::CoCreateInstance(CLSID_objtwo,NULL, CLSCTX_INPROC_SERVER, IID_Iobjtwo, (LPVOID *) &pobjtwo);
                       pobjtow-objtowFun1();
                     
                      如果是想调用Objectonw对象的实现,这样调用:
                      hr = ::CoCreateInstance(CLSID_objone,NULL, CLSCTX_INPROC_SERVER,  IID_Iobjone,  (LPVOID *) &pobjone); 
                      hr = pobjone->QueryInterface( IID_Iobjtow,  (LPVOID *)&pobjtow );              
                      pobjtow-objtowFun1();


    4:如果我们只想在一个对象添加多个接口,不想看见其他对象,我们可以屏蔽(注释)某个对象的源文件,.h和.cpp文件 和 OBJECT_ENTRY(CLSID_objtow, Cobjtow);

     

    示例:

    一:一个dll中一个组件对象关联多个接口:

         组件中,一个clsid关联多个iiid;

     

       调用方法:

     

     

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

     

    二:COM的调用(注:COM必须先注册):

     网上有关com调用的方法比较多,这里我详细说明一下:

     

    方法1:

    如果我创建了一个com组件,那么可以通过已有的文件调用导入调用com(这样就和directshow调用差不多了):


    #include " ..\ATLComDemo\ATLComDemo.h"
    #include "..\ATLComDemo_i.c"


    #include <atlbase.h>
    HRESULT QueryInterfacecom()
    {
     HRESULT hr = CoInitialize(NULL);
     
     
     Iobjone * pobjone = NULL;
     Iobjtow * pobjtow = NULL ;
        Iobjthree * pobjthree = NULL;
     
     //´´½¨COM ¶ÔÏóCobjoneʵÀý£¬Í¬Ê±»ñÈ¡CobjoneÏ嵀 Iobjone ½Ó¿Ú£»
     hr = ::CoCreateInstance(CLSID_objone,NULL, CLSCTX_INPROC_SERVER,  IID_Iobjone,  (LPVOID *) &pobjone);     if( FAILED( hr ) ){cout<<"hr";};
     pobjone->fun1();                                                                                              if( FAILED( hr ) ){cout<<"hr";};
     
     //»ñÈ¡CobjoneÏ嵀 Iobjtow ½Ó¿Ú£»
     hr = pobjone->QueryInterface( IID_Iobjtow,  (LPVOID *)&pobjtow );                                             if( FAILED( hr ) ){cout<<"hr";};
     pobjtow->fun3();
     
     //»ñÈ¡CobjoneÏ嵀 Iobjtow ½Ó¿Ú£»
     hr = pobjone->QueryInterface( IID_Iobjthree,  (LPVOID *)&pobjthree );                                         if( FAILED( hr ) ){cout<<"hr";};
     pobjthree->funthree1();
     pobjthree->funthree2();
     
     
     pobjone->Release();
     pobjtow->Release();
     pobjthree->Release();
     
     CoUninitialize();
     
     
     return hr;
    }#include <atlbase.h>
    HRESULT QueryInterfacecom()
    {
     HRESULT hr = CoInitialize(NULL);
     
     
     Iobjone * pobjone = NULL;
     Iobjtow * pobjtow = NULL ;
     Iobjthree * pobjthree = NULL;
     
     //´´½¨COM ¶ÔÏóCobjoneʵÀý£¬Í¬Ê±»ñÈ¡CobjoneÏ嵀 Iobjone ½Ó¿Ú£»
     hr = ::CoCreateInstance(CLSID_objone,NULL, CLSCTX_INPROC_SERVER,  IID_Iobjone,  (LPVOID *) &pobjone);     if( FAILED( hr ) ){cout<<"hr";};
     pobjone->fun1();                                                                                              if( FAILED( hr ) ){cout<<"hr";};
     
     //»ñÈ¡CobjoneÏ嵀 Iobjtow ½Ó¿Ú£»
     hr = pobjone->QueryInterface( IID_Iobjtow,  (LPVOID *)&pobjtow );                                             if( FAILED( hr ) ){cout<<"hr";};
     pobjtow->fun3();
     
     //»ñÈ¡CobjoneÏ嵀 Iobjtow ½Ó¿Ú£»
     hr = pobjone->QueryInterface( IID_Iobjthree,  (LPVOID *)&pobjthree );                                         if( FAILED( hr ) ){cout<<"hr";};
     pobjthree->funthree1();
     pobjthree->funthree2();
     
     
     pobjone->Release();
     pobjtow->Release();
     pobjthree->Release();
     
     CoUninitialize();
     
     
     return hr;
    }

     

    方法2:

    通过向导添加com组件到工程,这样组件中的接口类和相应的成员函数就显示到工程中了,想到ocx一样:

     

    调用方法:

    1:导入生成的头文件

    2: 声明对象,然后用CreateDispatch创建实例,参数为:com名.接口类名(类名不需要前面默认的I);

    3:最后释放示例;

     

    #include "atlone.h"

    void CTalonecomexeDlg::OnButton1()
    {
     // TODO: Add your control notification handler code here
     CoInitialize(NULL);
     
     
     Icomone Icomoneobj;

     if ( Icomoneobj.CreateDispatch("atlone.comone") !=0 )
     {
      Icomoneobj.fun1();

      Icomoneobj.fun2();
     }
     

      Icomoneobj.ReleaseDispatch();  
     
     CoUninitialize();
    }

     

     

     

    方法3:导入com组件后会生成相应的tlh,可以用下列方法使用dll;

    #import "../atlone/Debug/atlone.dll" no_namespace

    void CTDlg::OnButton1()
    {
     // TODO: Add your control notification handler code here
     
     CoInitialize(NULL);
     
     CLSID clsid;
     CLSIDFromProgID(L"atlone.comone",&clsid);
     
     Icomone * pcomone = NULL;

     HRESULT hr = CoCreateInstance( /*CLSID_comone*/clsid,NULL,CLSCTX_INPROC_SERVER,/*IID_Icomone*/__uuidof(Icomone), (void**)&pcomone );
     

     pcomone->fun1();
     pcomone->fun2();
     pcomone->Release();
     
     
     CoUninitialize();
     
     
    }

     

     

     

    //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    转载一篇VC调用com组件的文章:《vc中调用Com组件的方法详解》(注:没有全部验证)

     

    Requirement:
    1.创建myCom.dll,该COM只有一个组件,两个接口IGetRes--方法Hello(),IGetResEx--方法HelloEx();
    2.在工程中导入组件或类型库
    #import "组件所在目录myCom.dll" no_namespace 或
    #import "类型库所在目录myCom.tlb"
    using namespace MYCOM;

    ------------------------------------ Method 1 ------------------------------------
    CoInitialize(NULL);
    CLSID clsid;
    CLSIDFromProgID(OLESTR("myCom.GetRes"), //
    &clsid);//
    CComPtr<IGetRes> pGetRes; // 智能指针
    pGetRes.CoCreateInstance(clsid);
    pGetRes->Hello();
    pGetRes.Release(); // 小心哦,请看最后的“注意”
    CoUninitialize();
    ------------------------------------ Method 2 ------------------------------------
    CoInitialize(NULL);
    CLSID clsid;
    HRESULT hr = CLSIDFromProgID(OLESTR("myCom.GetRes"),
    &clsid);
    IGetRes *ptr = NULL;
    hr=CoCreateInstance(clsid,
    NULL,
    CLSCTX_INPROC_SERVER,
    __uuidof(IGetRes),
    (LPVOID*)&ptr);
    ptr->Hello();
    CoUninitialize();
    ------------------------------------ Method 3 ------------------------------------
    CoInitialize(NULL);
    HRESULT hr;
    CLSID clsid;
    hr = CLSIDFromProgID(OLESTR("myCom.GetRes"),
    &clsid);
    IGetRes* ptr = NULL;
    IGetResEx* ptrEx = NULL;

    // 使用CoCreateClassObject创建一个组件(特别是mutilThreads)的多个对象的时候,效率更高.
    IClassFactory* p_classfactory = NULL;
    hr=CoGetClassObject(clsid,
    CLSCTX_INPROC_SERVER,
    NULL,
    IID_IClassFactory,
    (LPVOID*)&p_classfactory);
    p_classfactory->CreateInstance(NULL,
    __uuidof(IGetRes),
    (LPVOID*)&ptr);
    p_classfactory->CreateInstance(NULL,
    __uuidof(IGetResEx),
    (LPVOID*)&ptrEx);
    ptr->Hello();
    ptrEx->HelloEx();
    CoUninitialize();
    ------------------------------------ Method 4 ------------------------------------
    直接从dll中得到DllGetClassObject,接着生成类对象及类实例(这方法可以使组件不用在注册表里注册,这是最原始的方法,但这样做没什么意义,至少失去了COM对用户的透明性),不推荐使用。
    // 定义一个函数指针类型
    typedef HRESULT (__stdcall * pfnHello)(REFCLSID,REFIID,void**);
    pfnHello fnHello = NULL; // 创建一个函数指针变量
    // 将COM组件DLL像一般DLL一样加载,得到DLL句柄
    HINSTANCE hdllInst = LoadLibrary("*:\*.dll");
    // 判断DLL加载是否成功
    if (NULL != hdllInst)
    {
    // 取得相应的函数地址
    fnHello = (pfnHello)GetProcAddress(hdllInst,
          "DllGetClassObject");
    if (NULL != fnHello)
    {
    // 得到类工厂接口指针
        IClassFactory* pcf = NULL;
    HRESULT hr = (fnHello)(CLSID_GetRes,
          IID_IClassFactory,
          (void**)&pcf);
          if (SUCCEEDED(hr) &&
          (pcf != NULL))
          {
    // 得到具体方法接口指针
          IGetRes* pGetRes = NULL;
          hr = pcf->CreateInstance(NULL,
          IID_IFoo,
          (void**)&pGetRes);
        if (SUCCEEDED(hr) &&
          (pGetRes != NULL))
          {
          pGetRes->Hello();
        pGetRes->Release();
    }
    pcf->Release();
        }
    }
    FreeLibrary(hdllInst);
    }
    ------------------------------------ Method 5 ------------------------------------
    通过ClassWizard利用类型库生成包装类,不过前提是com组件的接口必须是派生自IDispatch,具体方法:
    调出添加类向导(.NET中),选择类型库中MFC类,打开,选择"文件",选择"myCom.dll"或"myCom.tlb",接下来会出来该myCom中的所有接口,选择你想生成的接口包装类后,向导会自动生成相应的.h文件.这样你就可以在你的MFC中像使用普通类那样使用组件了.(CreateDispatch("myCom.GetRes") 中的参数就是ProgID通过Clsid在注册表中可以查询的到)
    CoInitialize(NULL);
    CGetRes getRest;
    if (getRest.CreateDispatch("myCom.GetRes") != 0)
    {
    getRest.Hello();
    getRest.ReleaseDispatch();
    }
    CoUninitialize();
    ------------------------------------ Notice------------------------------------
    COM中的智能指针实际上是重载了->的类,目的是为了简化引用记数,不需要程序员显示的调用AddRef()和Release(),但是为什么我们在Method 1中pGetRes.Release(),问题在于,我们的智能指针pGetRes生命周期的结束是在CoUninitialize()之后,CoInitialize所开的套间在CoUninitialize()后已经被关闭,而pGetRes此时发生析构,导致了程序的崩溃,解决这个问题的另一个方法是:
    CoInitialize(NULL);
    CLSID clsid;
    CLSIDFromProgID(OLESTR("myCom.GetRes"),
    &clsid);
    CComPtr<IGetRes> pGetRes; // 智能指针
    pGetRes.CoCreateInstance(clsid);
    pGetRes->Hello();
    // pGetRes.Release(); // 将其注释掉
    CoUninitialize();
    --------------------------------------------------------------------
    以上就是COM的5中方法,当然具体怎么使用还是要根据具体情况而定。

     

     

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

    转一篇关于com基本概念的文章:

    组件不一定就是一个dll,一个dll中可以包含很多个组件,而且一般见到的dll里也不止包含一个组件,一个dll里的每个组件都有自己的CLSID和ProgID。对于ATL工程来说,一个ATL Object就是一个组件,很明显,我们可以在一个工程里加入很多个ATL Object。

    对于ATL来说,一个组件对应着一个C++类,这在IDL中叫做coclass,一般情况下,一个coclas对应一个接口。实际上,一个coclass可以有很多个接口,这就是一个组件实现多个接口,并且这些接口共享一个组件中的函数。

    比如:coclass A有一个接口IA,接口导出了一个函数Foo(),那么coclass A里有一个Foo()函数来实现IA接口中的Foo()函数。后来想要对组件A升级,加入一个导出函数Foo2(),但是又不想影响以前的用户,当然重做 一个新组件是可以的,但是没有必要,并且有了重复代码。这时我们可以在组件A中新建一个接口IA2,IA2导出两个函数:Foo()和Foo2(),IA2仍然由coclass A来实现,也就是说现在coclass A里有了两个函数Foo()和Foo2(),接口IA和IA2共享coclass A里的Foo()函数。这样一来,以前的用户不用变化,因为接口IA没有改动,新的用户可以使用接口IA2,使用IA2也仍然可以完成IA的功能,因为时 而也有Foo()函数。

     

     

    展开全文
  • Com组件之:SmartUploead 组件应用范例教程,详细讲解了Java常用Com组件:SmartUploead 的使用方法,包括如何获取SmartUploead、实例、参数设置等,从事JAVA/JSP开发的朋友,掌握SmartUploead上传文件是很有必要的...
  • 这是一本介绍COM+的书籍, 不过只有pdg格式的, 没有PDF, 希望对大家有用:)
  • ActiveX组件是不是主要用于互联网交互,数据库也用ActiveX吗?主要还做些什么呢?
  • COM 组件设计与应用

    2016-06-22 07:40:43
    再过100年吧......”,但作为一名听话的好学生,我开始在书店里“踅摸”(注1)有关OLE的书籍(注2)。功夫不负有心人,终于买到了我的第一本COM书《OLE2 高级编程技术》,这本800多页的大布头花费了我1/5的月工资呀...
  • hadoop组件书籍列表

    2016-11-09 16:22:39
    hbase书籍 http://abloz.com/hbase/book.html
  • .net/Com 下找到对应的组件【如添加Microsoft.Office.Interop.Word 14.0.0.0的引用 】 1、(一般电脑上下载了相关的组件,在注册表中中注册DUID项的在Com里都能找到)。 2、com组件有独立的类型库文件,基于接口...
  • COM组件和DLL的区别

    千次阅读 2014-08-14 22:24:15
    这阵子在想一个需要利用com组件的小程序怎么做,突然想起上次去面试的时候考官问过autocad开发时为什么要利用com,而不采用一般的dll呢? 到google上查了一下,许多人也问了一样的问题:) 用com来写程序要比普通的...
  • COM编程精彩实例,是本老书了,不过书籍内容清晰,附带源码例子。
  • COM 技术内幕,COM原理及应用,深入解析COM 很好的技术书籍!初学者三本依次看成高手。
  • 主要涵盖了ATL内部架构和实现方法、运用向导简化ATL开发、C++/COM/ATL中字符串的使用技巧、理解并正确实现IUnknown、充分利用ATL提供的Smart ...COM群集/枚举、利用ATL Windows类建构独立的应用程序和UI组件等的技术内容...
  • 我想学习使用ATL来开发COM组件,我应该看什么书籍。 我想要我写的接口可以接收和发送数据,而且在接口中还会使用到多线程,等。 帮推荐几本书或者学习的一些网站
  • 有关于COM组件的经典书籍,详细介绍了组件的原理与应用。想学习Com技术的赶快下!
  • 完成了历史搜索和热门搜索之后,需要对用户输入的图书进行服务器的查询: 首先在search.js中定义一个函数,返回一个promise对象,用户获取用户查询出来的图书 用户除了自己输入以外,也可能通过点击历史记录或者...
  • 200dpi扫描 超清晰 Dale Rogerson写的Inside COMCOM(组件对象模型)的唯一经典书籍,Inside COM这本书是我最喜爱的书,也是启蒙我的书,用词幽默简单,这本书可以让程序员建立起大强的软件模型的观念,透过研究COM...
  • Com组件和Dll文件区别

    2015-11-12 10:54:00
    [转]COM组件和DLL的区别 2014-8-14阅读169评论0 com英文为Component Object Model(组件对象模型),是微软生产软件组件的标准。 它是构造二进制兼容软件组件的规范,不管组件应用何种语言编写只要遵循com规范...
  • 两本经典书籍对ATL和COM编程初学者来说必不可少
  • COM组件设计与应用

    2008-11-21 17:51:02
    再过100年吧......”,但作为一名听话的好学生,我开始在书店里“踅摸”(注1)有关OLE的书籍(注2)。功夫不负有心人,终于买到了我的第一本COM书《OLE2 高级编程技术》,这本800多页的大布头花费了我1/5的月工资呀...
  • CruiseYoung提供的带有详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《COM技术内幕——微软组件对象模型》一书的随书源代码 COM技术内幕——微软组件对象模型 基本信息 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 48,258
精华内容 19,303
关键字:

com书籍组件