中易网

vc 中使用com的方法

答案:2  悬赏:80  
解决时间 2021-03-06 02:02
c语言编程是需要头文件的,那那些com的头文件怎么得到呢,在其他开发语言中只要一个ocx文件就够了
最佳答案
随着Internet和Intranet应用的飞速发展,COM(Component Object Model,组件对象模型)以其巨大的潜力渗透到软件学科的各个领域。在Windows操作平台下,众多以COM形式提供的组件模块,如DirectX多媒体软件包、OLE DB/ADO数据库组件系统等,极大地丰富了操作系统的功能。由于COM机制允许任意两组件之间相互通信而不必关心是在何种计算机上的何种操作系统下运行,也不用关心组件是使用何种语言编制的,这使COM技术拥有了强大的生命力。尤其是Windows 2000同COM的下一代产品COM+的结合更加紧密,将使COM/COM+技术得到更广泛的应用。本文介绍在VC++ 6.0下编写COM客户程序的三种方法,虽然每一种方法都可以达到使用代码组件的目的,但详细了解并掌握所有方法会为根据具体情况选择适当方法提供更大的余地。

为叙述清楚,本文所用的程序框架均为对话框模式的MFC EXE工程。在编程前,首先要确定待操作的代码组件是否已经在系统中注册。如果代码组件没有注册,可以通过Windows\System目录下的regsvr32. exe程序对其进行注册。

COM库函数

利用COM库函数使用代码组件的方法是本文介绍的三种方法中实现起来最麻烦和困难的方法。它要求开发人员必须具有对COM原理的深入理解。该方法实现步骤如下:

1. 首先添加COM初始和终止代码。在应用程序类的初始化实例函数InitInstance()中添加如下代码:

CoInitialize(NULL);

……

CoUnInitialize();

上述语句运行在MFC框架/非MFC框架中,但由于本文程序使用MFC框架,所以也可以利用AfxOleInit()函数对其进行初始化。

2. 然后用#include 语句包含对组件头文件的引用并创建组件对象。在头文件中包含了接口的C++定义以及说明接口ID IID和类ID CLSID的符号化常量。创建工作在初始化对话框函数中进行:

IAccount pAccount=NULL;

……

CoCreateInstance(CLSID_Account,

NULL,

CLSCTX_INPROC_SERVER,

IID_Iaccount,

reinterpret_cast (&pAccount));

3. 最后释放组件对象。该工作应在程序退出之前完成,比如在消息WM_CLOSE的响应函数中进行:

if(pAccount!=NULL)

pAccount->Realease();

对该代码组件中的其他功能函数的调用,可以通过组件对象的接口指针pAccount来进行:

……

BSTR bstrResult;

PAccount-> Post(100,bstrResult);

SysFreeString(bstrResult);

……

由于COM支持类在comdef. h中定义,所以还要包含对该头文件的引用,才可以使程序正常运行。

类向导

通过类向导可以直接阅读组件的类型库,并产生包装类型库中每个接口的类,通过这些类的成员函数可以访问组件接口的方法和属性,与使用ActiveX控件的方法有些类似。

首先添加对COM组件进行初始化的代码。我们可以通过类向导的From a Type Library加入组件的.tlb类型库文件,并从中引入其接口类。在本例中引入的类型库文件中只包含一个从ColeDispatchDriver派生的组件包装类IAccount。通过包装类的成员,可以了解到组件接口能提供哪些服务,而且可以通过它们访问组件接口的方法和属性。

在初始化对话框函数里用COleDispatchDriver类的CreateDispatch()成员函数创建Account组件对象:

IAccount m_account;

……

m_account.CreateDispatch(“ATLSample.Account.1”));

其中ProgID值“ATLSample. Account. 1”可以通过Microsoft Visual Studio Tools 6.0里的OLE View工具查找到,其前提是该组件已被成功注册过。

释放Account组件对象也可以用COleDispatch-Driver类的ReleaseDispatch()函数来完成。

对于在COM库函数方法中用过的Post方法可用下述方法调用:

CString str=m_account. Post(100);

可以看出此种方法实现了同样的功能但实现起来要比上一种方法简单些,而且对理解COM的要求也不高。

#import 指令

#import 指令方法非常简便。对于类型库文件采用该指令是非常合适的,因为不管是调试版本还是发行版本,对于类型库文件而言,其路径是固定的。#import指令在执行时将会从待引入的类型库中提取出两个文件:一个.tlh文件和一个.tli文件,后者仅仅是包装类的函数实现,而前者则包含了许多有关的重要信息。智能接口指针也在其中定义:

_COM_SMARTPTR_TYPEDEF(IAccount,__uuidof(IAccount));

在实际编译时,编译器会将其展开成下述代码,并通过_com_ptr_t模板类为接口IAccount定义一个智能指针IAccountPtr。之所以说其是智能指针,是由于它替代IAccount时,会自动处理CoCreate-Instance和所有的 IUnknow方法,使用起来非常方便:

typedef _com_ptr_t<_com_IIID< Iaccount,__uuidof(IAccount)>> IAccountPtr;

由于有了智能指针,我们就可以调用_com_ptr_t模板类的CreateInstance()函数来完成对接口指针的创建工作:

IAccountPtr m_account=NULL;

m_account.CreateInstance(__uuidof(Account));

由于在生成的.tlh文件中包含结构声明和declspec(uuid(“”))声明,所以在这里可以很方便地用__uuidof(Account)获取接口的GUID。declspec(uuid(“”))声明将GUID和类及每个接口联系起来,允许开发人员以uuidof操作符来获取类和接口的GUID。

需要特别指出的是: 为防止原有代码和新引入的代码之间发生名字冲突,编译器会定义一个由类型库名称标识的命名空间,并在其中声明的任何名称内附加一个标识符。而为了避免指定命名空间标识,可以在#import 语句后加上using namespace,而且还可以用rename_namespace来改变命名空间。比如在本例中可以进行如下处理:

#import “Account.tlb” rename_namespace(“AccountDriver”)

using namespace AccountDriver;

这样,在使用智能接口指针IAccountPtr时只需定义即可:

IAccountPtr m_account;

至于对代码组件中的函数和属性的调用则同前两种方法一样,也是通过m_account来完成访问的。由于_com_ptr_t模板类和智能指针的引入,#import 指令方法是这三种方法中使用COM组件最简单的一种。
全部回答
好奇怪的提问,麻烦说具体点。 namespace就是一个空间而已、 如果你把class当文件夹,然后class里面的每个对象是文件的话 那么namespace就是磁盘。 你要访问一个文件夹,就要告诉编译器我用的是哪个磁盘的这个文件夹。 当然你也可以说,我如果不告诉你我用哪个磁盘,那么你就在这几个磁盘里面找,这就是using的作用了。 over 我觉得这个比喻还是很不错的~嘻嘻
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
深圳或者广州哪里有化妆品检测中心?
受武力值爆表是军人搞笑爽文
怎样看出一个男人是否深爱你?
求一部网游小说 我大概08到10年看过实体书 当
变比是什么意思
帆砍断了我的桅杆是什么歌,什么歌曲的歌词
电动车36伏250w电机可以用48伏的锂电池吗
骇客网吧地址在哪,我要去那里办事
小学生今年毕业算几届
为什么书上说“开元”是唐玄宗统治前期的主要
民天生鲜这个地址在什么地方,我要处理点事
华硕和清华同方哪个笔记本好点
求一部小说的名字,女主角叫姜落星。男主角叫
(1-2^2/1)(1-3^2/1)(1-4^2/1)...(1-100^2/1)
某lte基站将规划为超远的海域覆盖,请问规划
推荐资讯
怎样学说文解字五百四十部
《花田半亩》田维写的 哪能在线阅读
我想买一辆40万以下的7-8座吉普车家庭用,如
如何审计药品进销差价
我只有小学文化,我想学习,不知道该从那开始
吃油炸食品后总是口渴怎么办
roykim女友
好听的男英文名字
西就通讯这个地址在什么地方,我要处理点事
古希腊形成了一个统一的政治体 对吗
街道下水管网堵了,严重影响居民生活应该那个
求第一题,怎么求函数的有界区间?谢谢!(高
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?