1. 概念
ActiveX控件等价于以前的OLE控件或OCX。一个典型的控件包括设计时和运 行时的用户界面,唯一的IDispatch接口定义控件的方法和属性,唯一的 IConnectionPoint接口用于控件可引发的事件。
2. 控件框架
图 1
其中,_DClock和_DClockEvents这两个接口将为客户程序提供本控件的属性、方法以及可能响应的事件。接口是外部程序和控件进行通讯的协议,把接口看成是函数的集合,外部程序通过接口所暴露出来的方法访问控件的属性和方法。把接口看成抽象基类,在接口中定义的所有函数都是纯虚函数,函数的实现是在CClockCtrl类中完成。MFC通过底层封装,让CClockCtrl继承至_DClock接口,
全局函数DllRegisterServer()和DllUnregisterServer()分别用于控件在注册表的注册和注销,一般不需要对其进行改动。
应用程序类CClockApp从COleControlModule继承。而COleControlModule有是从CWinApp派生,提供了初始化控件模块的功能。
CClockPropPage的基类是COlePropertyPage,CDialog类的派生类,主要负责对属性页中对图形界面下用户控件属性的显示。
控件类CClockCtrl类是这几个类中比较重要的一个类,大部分实质性工作都在该类完成,其基类为COleControl,从CWnd继承,因此能够为控件对象提供与MFC窗口对象相同的功能同时也提供了一系列事件触发函数和一个分发映射表,使ActiveX控件能够同包容器程序有效地进行交互。该类的派生类将可以在满足特定的条件时向控件的包容器发送消息或是触发事件,以通知包容器程序在控件内有一些重要的事件发生。分发映射表是其中很重要的一个部分,负责向包容器程序暴露控件提供的方法和属性。调度映射是MFC提供的一种映射机制,主要是为了让外部应用程序可以方便地访问控件的属性和方法,而事件映射也是MFC提供的一种映射机制,让控件可以向包含它的容器发送事件通知。图2展示了COleControl类在控件与包容器通信中所起的作用。可以看出,ActiveX控件与其包容器之间的所有通信过程都是由COleControl来完成的:
图2COleControl在ActiveX控件与包容器通信中的作用
图2
3. 属性页
添加颜色属性页:
BEGIN_PROPPAGEIDS(CClockCtrl, 2)
PROPPAGEID(CClockPropPage::guid)
PROPPAGEID(CLSID_CColorPropPage)
END_PROPPAGEIDS(CClockCtrl)
图 3
4. 属性
l 属性种类
Stock:为每个控件提供的标准属性,如字体或颜色。
Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被更改,但控件可以使用它们调整自己的属性。
Extended:这些是由容器处理的属性,一般包括大小和在屏幕上的位置。
Custom:由控件开发者添加的属性。
l 自定义属性
图 4
Member variable:添加了一个变量和一个变量改变时的响应函数。
Get/Set methods:添加一个设置变量函数和一个获取变量函数。
l 添加关联属性变量
图5
l 持久性
/
// CClockCtrl::DoPropExchange - Persistencesupport
void CClockCtrl::DoPropExchange(CPropExchange*pPX)
{
ExchangeVersion(pPX,MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
//TODO: Call PX_ functions for each persistent custom property.
PX_Short(pPX,"Interval",m_interval,1000);
}
添加PX_函数为变量添加持久性。
l 通知容器,
BoundPropertyChanged函数通知容器我的属性属性改变
l 设计时和使用时状态设置
利用环境属性AmbientUserMode判断
5. 事件
l 源接口
[default,source] dispinterface _DClockEvents;
控件将用这个接口来发送通知事件,这个接口不是控件本身实现的接口。一方调用接口的方法,另一方实现接口的方法。调用_DClockEvent的方法向容器发送事件通知,控件使用这个接口的方法,由容器去实现接口方法。
l 自定义事件
对于库存事件的发出,发起库存事件的通知和过程被底层屏蔽了。对以自定义的事件,必须某一个条件到达时,显示的调用这个函数。