admin管理员组

文章数量:1531528

2024年7月3日发(作者:)

一、ActiveX控件

1、初识ActiveX控件

ActiveX控件可以看做是一个极小的服务器应用程序,它不能独立运行,必须嵌入到某个容

器程序中,与该容器一起运行。容器应用程序是可以嵌入或链接对象的应用程序。服务器应

用程序是创建对象并且当对象被双击时,可以被启动的应用程序。我们常用的Word就是一

个容器应用程序,例如,若在Word文档中可以嵌入或链接一个Excel表格对象,则这时的

Excel就是服务器应用程序。在双击Word文档中嵌入或链接的这个Excel表格对象后,将启

动Excel程序来完成对这个表格的编辑工作。Excel就是拥有这个表格对象的服务器应用程

序,而Word程序则是可以容纳这个表格对象的容器应用程序。另外,我们也可以在Excel

文档中嵌入或链接一个Word文档对象,因此对Word来说,它不仅仅只是一个容器应用程

序,同时它也是一个服务器应用程序。对ActiveX来说,它的底层实际上采用COM技术或

采用ATL技术实现的。

2、实例讲解,用VC++编写一个ActiveX时钟控件

(1)、选择【File/New】菜单项,选择Projects选项卡,在列表框中选择MFC ActiveX

ControlWizard,工程名设为Clock。利用MFC ActiveX ControlWizard向导创建的工程自动生

成三个类,CClockApp类相当于应用程序类,CClockCtrl类相当于主窗口类或视类,

COlePropertyPage类是一种类似于对话框的图形界面,用于显示控件的属性。其中还生成了

相应的接口_DClock和_DClockEvents,接口是控件与外部程序进行通信的协议。可以把接

口看做是函数的集合,外部程序通过这个接口所暴露出来的方法去访问控件的属性和方法。

实际上,可以把接口看做是一个抽象基类,在此接口中定义的所有函数都是纯虚函数,这些

函数的实现是在CClockCtrl类中完成的。MFC通过底层的封装,让CClockCtrl类继承自接

口_DClock,所以通过该接口调用的函数实际上调用的是CClockCtrl类中真正实现的函数。

说明:CClockCtrl类头文件中,不仅提供了一个消息映射,还提供了一个调度映射和事件映

射。其中调度映射是MFC提供的一种映射机制,主要是为了让外部应用程序可以方便地访

问控件的属性和方法,而事件映射也是MFC提供的一种映射机制,让控件可以项包含它的

容器发送事件通知。

(2)、在VC++开发环境中运行ActiveX控件程序,将出现一个对话框,让用户选择一个可执

行的程序,因为ActiveX控件不能独立运行,它必须嵌入到一个容器中。单击该对话框上一

个向右箭头的按钮,在弹出的快捷菜单中选择ActiveX Control Test Container,也就是说,选

择ActiveX Control Test Container作为ActiveX控件的容器,该容器位于VC安装目录下的

CommonTools目录下,程序名为。

(3)、ActiveX Control Test Container加载特定的ActiveX控件,选择【EditInsert New Control】

菜单项,在左边列表框中选择一个控件,在键盘上快速连续地按下C、L、O键,就可以直

接定位到刚生成的Clock控件。

(4)、ActiveX控件的注册,开始->运行->输入regsvr32 "C:Program FilesMicrosoft Visual

"->单击确定,完成注册。也可以用【Tools/Register

Control】菜单项完成控件的注册,该菜单项就是调用regsvr32。

提示:可将拖动到运行对话框,此时会自动生成的完整路径。regsvr32

/u可用于删除ActiveX控件的注册信息。regsvr32实际上是调用ActiveX控件的

DllRegisterServer 函数完成注册,regsvr32 /u实际上是调用ActiveX控件的

DllUnregisterServer函数删除控件的注册信息。

注意:所有的ActiveX控件必须在注册之后才能使用。VC开发环境中,生成ActiveX控件

时,会自动注册该控件。若ActiveX控件处于加载状态,该控件将不能被VC开发环境编译

执行,应取消该控件的所有加载。

(5)、编写ActiveX控件,实现系统时间的显示。为CClockCtrl类添加WM_CREATE消息处

理函数OnCreate,在该函数中设置定时器SetTimer(1,1000,NULL)。再为CClockCtrl类添加

WM_TIMER消息处理函数OnTimer,在该函数中使窗口无效Invalidate(),以便重绘。在

CClockCtrl类的OnDraw函数中添加如下代码实现时间显示:

CTime time=CTime::GetCurrentTime();

CString str=("%H:%M:%S");

pdc->TextOut(0,0,str);

提示:可以调用COleControl类的InvalidateControl成员函数,让控件窗口重绘,若该函数

的参数是NULL,则所有控件都将被重绘。

3、ActiveX控件的属性

(1)、ActiveX控件中有四种属性:

▲Stock:为每个控件提供的标准属性,如字体或颜色。

▲Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被更改,但控件

可以使用它们调整自己的属性。

▲Extended:这些是由容器处理的属性,一般包括大小和屏幕上的位置。

▲Custom:由控件开发者添加的属性。

(2)、为Clock控件添加背景色和文本颜色的标准属性

Ⅰ、VC开发环境中,若要为控件添加属性,可打开ClassWizard,切换到Automation选项

卡,Class name选择CClockCtrl,单击Add Property按钮,External name下拉列表框中选择

BackColor(背景色),保持默认的Stock选项,单击OK按钮即为控件添加了背景色属性。同

样,可以添加文本颜色的属性ForeColor。

Ⅱ、在CClockCtrl类的OnDraw函数中实现背景色和文本颜色的改变:

// GetBackColor得到BackColor属性值,TranslateColor将OLE_COLOR类型的值转换为

COLORRGB类型的值。

CBrush brush(TranslateColor(GetBackColor()));

pdc->FillRect(rcBounds,&brush);//设置控件的背景色

pdc->SetBkMode(TRANSPARENT);//设置文本背景为透明

pdc->SetTextColor(TranslateColor(GetForeColor()));//设置控件的文本颜色

提示:在VB的开发环境中,提供了一个控件属性面板。这时,已经可以在该控件属性面板

中设置颜色属性了。

Ⅲ、为Clock控件添加颜色属性页。在CClockctrl类的源文件中,BEGIN_PROPPAGEIDS

和END_PROPPAGEIDS宏之间添加PROPPAGEID(CLSID_CColorPropPage),同时修改

BEGIN_PROPPAGEIDS的第二个参数(表示属性页的总数)为2。ActiveX Control Test

Container中加载Clock控件后,【Edit特性】菜单项就可以调出控件自身的属性表单。

(3)、为Clock控件添加自定义的属性:时间间隔。

Ⅰ、在ClassWizard的Automation选项卡中,Class name选择CClockCtrl,然后单击Add

Property按钮,External name输入Interval,Type选择short,Variable name自动设置为

m_interval,Notification function自动增加一个通知函数OnIntervalChanged,外部修改该属

性时,这个函数将被调用。在OnIntervalChanged函数中根据用户输入的时间间隔值控制

Clock控件的显示更新:

void CClockCtrl::OnIntervalChanged()

{

if (m_interval<0||m_interval>6000)

{//若时间间隔超出范围,则设置为1000

m_interval=1000;

}

else

{//将类似2456的值转换为2000

m_interval=m_interval/1000*1000;

}

KillTimer(1);//删除原来设置的计时器

SetTimer(1,m_interval,NULL);//使用新的计时器

SetModifiedFlag();//设置属性被修改的标记

}

注意:Clock控件放到VB环境中,会执行CClockCtrl类的OnCreate函数。而在VC的对话

框上插入Clock控件时,却没有调用CClockCtrl类的OnCreate函数,此时,KillTimer函数

会出现非法操作。

Ⅱ、使用【Edit/Insert New Control】命名项加载Clock控件后,选中该控件,然后单击

【ControlInvoke Methods】菜单项,在Method Name下拉列表中,选择Interval(PropPut)项,

在Parameter编辑框中输入数值,单击【Set Value】按钮设置Interval属性值。最后,单击

【Invoke】按钮让设置生效。

Ⅲ、为Clock控件添加设置时间间隔的属性页。在VC开发环境中,切换到Clock工程的

ResourceView选项卡,打开IDD_PROPPAGE_CLOCK对话框资源,设计该对话框如下:

然后,在ClassWizard的Member Variable选项卡中,为ID为IDC_EDIT_INTERVAL编辑框

控件关联一个成员变量,Member variable name输入成员变量名m_updateInterval,Variable

type选择short,Optional property name指定控件属性的External name,这里指定为Interval。

(4)、为Clock控件添加自定义的方法。

Ⅰ、打开ClassWizard的Automation选项卡,class name选择CClockCtrl,然后单击【Add

Method】按钮,External name输入Hello,Internal name自动生成为Hello,Return type设为

void。在CClockCtrl类中编写Hello函数输出字符串Hello。

Ⅱ、利用ActiveX Control Test Container容器中加载Clock控件,选择【ControlInvoke Methods】

菜单项,Method Name下拉列表框中选择Hello方法,然后单击【Invoke】按钮,就会调用

Clock控件的Hello方法。

(5)、属性的持久性即用户设置完属性后,下次打开程序时,该控件的属性值仍能保持不变

Ⅰ、在CClockCtrl类的DoPropExchange函数中添加如下语句,让属性具有持久性:

PX_Short(pPX,"Interval",m_interval,1000);// Interval是提供给外部程序使用的属性的名称,

m_interval与属性相关联的类的成员变量,1000是指定属性的默认值。

Ⅱ、当Interval这个属性值发送改变时,会调用Clock控件,即CClockCtrl类的

OnIntervalChanged函数,可在该函数中通知控件的容器Interval这个属性值发生了改变:

BoundPropertyChanged(0x1);// 0x1是属性的调度ID,在文件中可以找到,如:

[id(1)] short Interval;

(6)、环境属性,UserMode环境属性可用于判断当前处于设计模式还是运行模式

Ⅰ、在CClockCtrl类的OnTimer中修改如下:

if (AmbientUserMode())//若处于运行模式

{

InvalidateControl(NULL);//重画控件,否则让其静止

}

提示:在编程过程中,有时可以根据控件的环境属性调整控件的行为。若想得到环境属性,

可以利用Ambient开头的函数去获取。读者可以在MSDN中查看这些函数的用法。

Ⅱ、在ActiveX Control Test Container容器中加载Clock控件,【Options】菜单下的【Design

Mode】菜单项可设置设计模式还是运行模式。

(7)、生成发行版本的ActiveX控件

VC开发环境中,选择【BuildSet Active Configuration】菜单项,从弹出的对话框中选

择”Clock-Win32 Release”这一项,单击【OK】按钮,重新编译执行后,就可以生成发行版

本了。

说明:通常都是在Win32 Debug模式下,也就是调试模式下进行开发。在此模式下有助于

我们发现程序编写过程中发生的一些错误(例如非法访问错误),还可以帮助我们调试程序、

跟踪程序,进而排查错误。但是,在调试方式下生成的可执行文件,或者控件文件,往往都

比较大,因为在这些文件中包含了一些调试信息。在开发完成之后,可以选择Win32 Release

方式,重新生成可执行文件,或控件文件。在发行模式下进行编译时,VC编译器会对程序

作一些优化,如,在代码生成上和执行速度上作一些优化,同时,生成的可执行文件或控件

文件都比较小,因为其中没有再包含调试信息了。

二、ActiveX控件的事件

ActiveX控件有两种事件:标准事件和自定义事件

1、添加标准事件

Ⅰ、打开ClassWizard的ActiveX Events选项卡,Class name选择CClockCtrl,然后单击【Add

Event】按钮,External name中选择Click标准事件。

提示:添加的Click标准事件后,在文件的最后可以看到:

[default] dispinterface _DClock;

[default, source] dispinterface _DClockEvents;

其中source标识表明_DClockEvents接口是一个源接口,源接口表示控件将使用这个接口来

发送通知事件,这个接口不是控件本身实现的接口。实际上,_DClockEvents接口中的方法

是由容器实现的。

Ⅱ、利用ActiveX Control Test Container容器中加载Clock控件,当鼠标单击控件时,在容

器下面的窗口中可以看到Clock Control:Click这句话。

2、添加自定义事件

Ⅰ、在VC开发环境中,切换到ClassView选项卡,右键单击_DClockEvents接口,从弹出

的快捷菜单中选择【Add Event】菜单项。External name输入NewMinute,Internal name中

自动生成FireNewMinute,单击OK按钮。在CClockCtrl类的OnDraw函数中,在调用

GetCurrentTime函数后添加:

if (0==ond())//若当前秒数为0,即到达了新的一分钟

{

FireNewMinute();//向容器发出NewMinute事件通知

}

Ⅱ、利用ActiveX Control Test Container容器中加载Clock控件,当控件上显示的时间一旦

达到新的一分钟时,该容器下面的窗口中就会显示Clock Control:NewMinute语句。

3、编写程序对ActiveX控件进行测试

(1)、新建一个基于对话框的MFC工程ClockTest。为ID为IDD_CLOCKTEST_DIALOG的

对话框添加自己生成的Clock控件,在对话框中单击鼠标右键,在弹出的快捷菜单中选择

【Insert ActiveX Control】菜单项,选择Clock控件,单击【OK】按钮完成控件的添加。另

一种插入ActiveX控件的方法是,选择【ProjectAdd To ProjectComponents and Controls】菜

单项,双击”Registered ActiveX Controls”目录,在此目录中找到Clock控件进行插入,此方

法与上一种方法的区别在于:该方法会为控件生成一个类CClock,该类基类是CWnd,该

类封装了对这个控件进行访问的一些操作;同时,在工具箱上也增加了Clock控件的图标。

提示:在控件上单击鼠标右键,在弹出的快捷菜单中选择【特性】菜单项,即可显示该控件

的属性表单。单击VC开发环境中左下角的测试按钮,可以测试控件的运行。

(2)、在程序中动态添加Clock控件

为CClockTestDlg类添加一个私有的成员变量m_clock,类型为CClock,并且在CClockTestDlg

类的头文件中包含CClock类的定义。可用Create函数创建该控件:

m_("Clock",WS_CHILD|WS_VISIBLE,CRect(0,0,100,50),this,123);//创建控件

m_();//调用控件的Hello方法

m_kColor(RGB(0,0,255));//设置背景色,Clock控件的封装类CClock中的方法调

用了控件中相应的设置属性的方法,VC中,对属性和方法的访问都是通过相应函数来访问

的。

m_eColor(RGB(255,0,0));

(3)、VC中访问ActiveX控件的事件的方法

在对话框资源中放置一个Clock控件,在控件上单击鼠标右键,选择ClassWizard,Message

中选择事件,然后单击Add Function完成事件的添加。也可以在控件上单击鼠标右键,从弹

出的快捷菜单中选择【Events】菜单项,为Clock控件添加事件。事件添加后,VC会自动

在的BEGIN_EVENTSINK_MAP宏中添加代码。

三、VB测试ActiveX控件

VB作为ActiveX控件的测试容器是非常方便的,在VB开发环境中,新建一个Standard EXE

工程,加载一个ActiveX控件的步骤是:单击【ProjectComponents】菜单项,从本机当前

可用的所有ActiveX控件选择相应的控件。一个典型的ActiveX控件,它具有方法、属性、

事件这三种特性。在VB开发环境中,查看一个加载的ActiveX控件的方法、属性、事件这

三特性,可以选择【ViewObject Browser】菜单项,在弹出的对象浏览器对话框中,在All

Library下拉列表中选择要查看的控件,右边窗格中就会显示相应的信息,其中绿色小方块

图标项是该控件提供的方法,小手图标项是控件提供的属性,闪电图标项是控件提供的事件。

提示:OCX是ActiveX控件的一种后缀名,ActiveX控件对应的文件也可以是其他后缀名,

如DLL。一个OCX文件中可以包含多个ActiveX控件。

本文标签: 控件属性函数添加容器