[
而在MFC中,通过类嵌套来实现。MFC库有一组宏可以自动实现这个过程。
INTERFACE_PART宏产生嵌套类,并为特定的接口函数产生原型,并加上QueryInterface,AddRef
和Release的原型。
DECLARE_INTERFACE_MAP宏产生一张表的声明,该表包含了所有类接口的ID。CCmdTarget::
ExternalQueryInterface()函数使用该表来获取接口指针。
3.另一个有用的接口--类厂(CLASS FACTORY)
CLASS FACTORY是一种类,是被用来支持名为IClassFactory的特殊的COM接口。IClassFactory
是从IUnknown派生的,它的主要成员函数是:CreateInstance(),它产生的原因是在COM
中我们无法直接调用构造函数,于是只好让组件来决定如何构造对象,为此组件提供了类厂
,从而将具体的创建过程封装起来。利用类厂来创建多个对象。MFC库采取动态创建技术来解
决这一问题,一个名为COleObjectFactory的类可以在运行时创建任何类。采用DYNCREATE宏
设置标准的动态创建机制。OLECREATE宏声明和定义了一个COleObjectFactory类的全局对象
,使用指定的唯一CLSID。在DLL组件中,倒出函数DllGetClassObject根据OLECREATE宏设置
的全局变量,找到特定的类厂对象,并返回指向该对象的指针。当DLL被初始化时,RegesterAll
被调用,在EXE组件中,初始化代码调用静态的COleObjectFactory::RegisterAll函数
,该函数查找所有的厂对象,并调用CoRegisterClassObject注册每一个对象。
接口集、接口、接口函数、属性之间的关系。
个人认为:接口集、接口、接口函数(方法)、属性在逻辑上存在着一定的对应的关系。接
口集包含多个接口。一个接口包含着一类接口函数,每一接口函数对应着一类属性。接口函
数才是用户所关心的,用户只有通过接口使用接口函数才能改变属性。属性与接口函数都是
对组件对象的抽象。
4.AUTOMATION & ACTIVE X
AUTOMATION & ACTIVE X是ACTIVE X组件的重要部分。ACTIVE X控件也是小型的AUTOMATION服
务器。AUTOMATION让应用程序告诉它做什么。它揭示属性和方法。如果我们揭示了自己应用
程序的所有方法和属性,则使用AUTOMATION应用程序的任何编程语言都能成为自己应用程序
的书写语言。知道有关与AUTOMATION交互的最主要的事情总有一个程序在控制着。控制着的
应用程序称AUTOMATION控制器,揭示方法和属性的应用程序称为AUTOMATION服务器。
AUTOMATION通讯实际上已经明确定义了主从关系。主是自动化客户程序,从是自动化组件(
控件)。通过构造一个组件对象,或者与已经运行的程序中的现存对象建立连接,客户程序
可以对相互作用过程进行初始化,然后客户程序可以调用组件程序中的接口函数,并且将那
些已完成的接口释放掉。
这意味着WORD ,EXCEL,ACCESS及VB这些支持AUTOMATION的应用程序,可以被连接到与AUTO
MATION兼容的组件中。我们用VC++就可以调用WINDOWS下的任何控件(即使它包含在WORD 或
其他程序中),也可以用VC++自己编写组件,而用VBA宏来对它进行调用。
(1)IDispatch是自动化的核心。它将所有的内部模块通讯都汇集在IDispatch::Invoke()
上,像IUnknown和IClassFactory一样,它完全被COM调度(marshaling)所支持。从组件一
方面来看,我们需要有一个具有IDispatch接口(包含必要的类厂)的COM类;从用户方面来
看,我们使用标准的COM技术来获取指针。
interface IDispatch:public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(
UINT iTInfo,
LCID lcid,
ITypeInfo _RPC_FAR *_RPC_FAR *ppTInfo)=0;
virtual HRESULT STDMETHODCALLTYPE GetIDsofNames(
REFIID riid,
LPOLESTR _RPC_FAR *rgszNames,
LCID lcid,
DISPID _RPC_FAR *rgDispId)=0;
virtual HRESULT STDMETHODCALLTYPE Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlag,
DISPPARAMS _RPC_FAR *pDispParams,
VARIANT _RPC_FAR *pVarResult,
EXCEPINFO _RPC_FAR *pExcepInfo,
UINT _RPC_FAR *puaArgErr)=0;
};
说明:Invoke()函数是其中最主要的函数,用于调用AUTOMATION服务器的函数和属性。
(2)IDispatch 的实现:
组件程序可以有几种方法来实现IDispatch接口。最通常的做法是把大部分工作交给WINDOWS
的COM DLL,这可以通过调用COM函数CreateStdDispatch来实现,或把Invoke调用委托给
ITypeInfo接口,由它来处理组件的类型库(type library)。一个类型库是一张表,该表允许
客户查找组件中的对象方法和属性的符号化名字。MFC支持类型库,但在IDispatch的实现中
并没有用到类型库。IDispatch的实现是靠分发映射(DISPATCH MAP)驱动的。MFC程序根本
不调用CreateStdDispatch,它也不用类型库来实现IDispatch::GetIDsOfName。
(3)MFC 的分发映射是如何与IDispatch和Invoke成员函数相关连?
分发映射宏在内部产生了一个数据表,MFC中的Invoke函数可以读到该表。控制程序可以得
到类的IDispatch指针。并且用一个指针数组作为参数调用Invoke。MFC的Invoke函数的执行
体会利用类分发映射对所提供的指针进行解码,可以调用某个成员函数。
(4)关于VARIANT类型:
自动化客户和组件都用到了VARIANT类型。它是一个通用数据类型,是64位数据。IDspatch:
:Invoke利用它来传递参数和返回值。
BEGIN_DISPATCH_MAP(CWwddCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CWwddCtrl)
DISP_PROPERTY_NOTIFY(CWwddCtrl, "Wdlowline", m_wdlowline, OnWdlowlineChanged, VT_R4)
DISP_PROPERTY_NOTIFY(CWwddCtrl, "Wdcaption", m_wdcaption, OnWdcaptionChanged, VT_BSTR)
DISP_PROPERTY_NOTIFY(CWwddCtrl, "Wdxmean", m_wdxmean, OnWdxmeanChanged, VT_BSTR)
DISP_PROPERTY_NOTIFY(CWwddCtrl, "Wdymean", m_wdymean, OnWdymeanChanged, VT_BSTR)
DISP_FUNCTION(CWwddCtrl, "setwdobject", setwdobject, VT_EMPTY, VTS_I4)
DISP_FUNCTION(CWwddCtrl, "setwdproper", setwdproper, VT_EMPTY, VTS_I4)
DISP_FUNCTION(CWwddCtrl, "deletelist", deletelist, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CWwddCtrl, "addwdvalue", addwdvalue, VT_EMPTY, VTS_R4)
DISP_FUNCTION(CWwddCtrl, "setambie", setambie, VT_EMPTY, VTS_R4 VTS_R4 VTS_R4)
END_DISPATCH_MAP()
2.Active X控件
一个典型的空间包括设计时和运行时的用户界面,唯一的IDispatch接口定义控件的方法和属
性,唯一的IConnectionPoint接口用于控件可引发的事件。除此之外,一个控件还可以包含对
其整个生命周期的一执性支持,以及对剪贴,拖放等用户界面特性的支持。从结构上看,一
个控件有大量必须支持的COM接口,以利用这些特性。Active X控件永远是放在其所放置的容
器内运行的,空间的扩展名为.OCX,但从运行模块的角度看,它不过是一个标准的WINDOWS
DLL文件。
属性和事件是容器内应用程序与控件通讯的方式,容器和控件之间的通信使用事件。对于
ActiveX控件,事件是在容器端时显现的IDispatch接口。事件的底层机制称连接点。一个连接
点就是与容器通讯所需接口的类型描述,连接点不只限于IDispatch接口,它也可用任何COM
实现,控件只不过第一个利用他们。
ACTIVEX 是一个独立的对象,可以激起和相应事件,处理消息,具有唯一的属性,并有多线程能
力,并支持其余容器之间的双向通信和消息传递.ACTIVE X控件最奇妙的地方在于它的可编程
性和克重复使用性.它对外部环境是开放的,能被各种编程合肥编程环境使用.控件对外有三个
属性集.(属性,对象,方法)
[本文共有 2 页,当前是第 2 页] <<上一页 下一页>>
]