基于MFC的ActiveX控件开发
ActiveX 控件是基于组件对象模型 (COM) 的可重用软件组件,广泛应用于桌面及Web应用中。在VC下ActiveX控件的开发可以分为三种,一种是直接用COM的API来开发,这样做显然非常的麻烦,对程序员要求也非常高,因此一般是不予考虑的;一种是基于传统的MFC,采用面向对象的方式将COM的基本功能封装在若干MFC的C++类中,开发者通过继承这些类得到COM支持功能。MFC为广大VC程序员所熟悉,易于上手学习,但缺点是MFC封装的东西比较多,因此用MFC开发出来的控件相对会比较大,因此比较适于开发桌面ActivexX控件,尤其是有GUI界面的控件。第三种就是基于ATL的,ATL可以说是专门面向COM开发的一套框架,使用了C++的模板技术,在运行时不需要依赖于类似MFC程序所需要的庞大的代码模块,更适合于Web应用开发。
本文介绍的是采用第二种方式,即应用MFC进行桌面可视控件开发的方法步骤,开发环境则是基于VC2005。 1.创建控件项目
打开VC2005后,我们要先创建一个项目,在新建项目页的左侧选择Visual C++-MFC,在右侧选择MFC ActiveX控件,填上解决方案和项目名称,比如在这里我的项目名称是activexdemo1,解决方案名称是activexdemo。
然后进入控件向导页,在向导的第二页有个运行时许可证,选中这个的话会在生成控件的同时生成一个许可证文件,其他用户在使用这个控件的时候必须同时附有这个许可证,在此我们保持默认状态,不选。
1
下一页是关于项目中各部分的命名问题,可以根据需要自定义,这里就按默认的情况不做修改了。
下一页是选择控件基于哪种控件的扩展以及控件的一些基本特性。如果新建的控件是基于某种特定控件的话,就在创建的控件基于下选择所要继承的控件名,否则就保持none。下方的附加功能根据实际需要进行选择,并且可以将鼠标放置于选项上方,功能的说明会自动显示在动态出现的小提示信息窗口中。选择完毕点击完成,向导就根据你的选择生成新项目。
2
进入开发环境,我们可以先看一下类视图。
其中的Cactivexdemo1App是我们这个控件的主程序模块,定义了控件的注册(DllRegisterServer)、删除(DllUnregisterServer)等功能,一般不用动,如有需要我们可以在其中的InitInstance和ExitInstance中定义我们自己的初始化和终止操作代码,一般也就是一些资源的初始化和销毁工作。
Caxtivexdemo1Ctrl是控件类,我们要做的控件功能基本上就是要在这个类中实现。 需要提一下的是在这个类中重写了父类的OnDraw函数,有如下两句代码: pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds);
也就是在控件上画了一个椭圆,实际控件开发中可以根据功能需要修改重写这个函数来绘制控件界面。
Caxtivexdemo1PropPage是属性页类,这个类实现了一个在开发时设定控件属性的对话框。 activexdemo1Lib是为客户程序提供本控件的属性、方法以及可能响应的事件的接口的库节点,在添加控件的这些功能的时候会用得到。
3
其中的Cactivexdemo1App是我们这个控件的主程序模块,定义了控件的注册(DllRegisterServer)、删除(DllUnregisterServer)等功能,一般不用动,如有需要我们可以在其中的InitInstance和ExitInstance中定义我们自己的初始化和终止操作代码,一般也就是一些资源的初始化和销毁工作。
Caxtivexdemo1Ctrl是控件类,我们要做的控件功能基本上就是要在这个类中实现。 需要提一下的是在这个类中重写了父类的OnDraw函数,有如下两句代码:
pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); pdc->Ellipse(rcBounds);
也就是在控件上画了一个椭圆,实际控件开发中可以根据功能需要修改重写这个函数来绘制控件界面。
Caxtivexdemo1PropPage是属性页类,这个类实现了一个在开发时设定控件属性的对话框。 activexdemo1Lib是为客户程序提供本控件的属性、方法以及可能响应的事件的接口的库节点,在添加控件的这些功能的时候会用得到。 2.生成并测试控件
好,现在我们就可以先来生成一下这个项目,当然到目前我们只是用系统自动生成的一个控件项目,什么功能都没有,只是一个空框架。
几秒钟后,项目应该是顺利生成。控件也被自动注册到系统中去。那怎么才能测试一下这个控件呢?当然你可以再建个新项目,比如一个对话框程序,在对话框资源编辑窗口中右边的工具箱里鼠标右键菜单里点选择项。
4
从弹出窗口中的COM组件下找到我们刚刚生成的这个控件,打勾选中。
然后在工具箱里就会出现这个控件。
然后用鼠标拖到对话框里就能用这个控件了。
5
除了这种方法,VS还提供了一种简便的控件测试工具。在VisualStudio中菜单的工具下有个ActiveX控件测试容器。
在
工
具
栏
里
点
新
控
件
按
钮
。
在插入控件对话框中找到并选择我们的这个控件。
6
然后就能在这个容器中测试控件的各种功能了。
3.事件
ActiveX 控件使用事件通知容器控件上发生了某些事情。事件的常见示例包括单击控件、使用键盘输入数据和控件状态更改。当发生这些操作时,控件将引发事件以提醒容器。 MFC 支持两种事件:常用和自定义。常用事件是 COleControl 类自动处理的事件。自定义事件使控件得以在该控件特定的操作发生时通知容器。控件内部状态发生更改或收到某个窗口消息即属于此类事件。 常用事件
常用事件由 COleControl 类自动引发。COleControl 包含预定义成员函数,它们引发常见操作所导致的事件。一些由 COleControl 实现的常见操作包括单击和双击控件、键盘事件和鼠标按钮状态发生更改。
添加常用事件的操作是在类视图中右击ActiveX 控件类,比如在此例中就是Caxtivexdemo1Ctrl。在菜单中选择添加事件,打开添加事件向导。
7
在添加事件向导中的事件名称中选择Click,也就是鼠标点击事件,添加到控件中。然后再选中类视图中库节点下的第三个节点,也就是Dactivexdemo1Events。在下面就能看到我们刚刚添加的这个事件。
然后生成新的控件程序,我们来看看测试一下这个新事件。
打开上面提到的ActiveX控件测试容器,把这个控件添加进来,用鼠标点击控件,就会在程序下方的消息栏中看到activexdemo1 Control: Click这样的消息,这就是我们添加进去的鼠标相应事件。
8
那在开发环境中使用控件的时候是什么样子的呢?好,像上面提到过的那样新建一个对话框项目,把控件放到对话框上。选中这个控件,在属性窗口中的控件事件中就有这个Click事件了,如果在使用控件中需要相应鼠标点击事件,就点添加ClickActivexdemo1ctrl1,事件响应函数中添加你需要的功能了。
比如像这样:
void CtestMFCDlg::ClickActivexdemo1ctrl1() {
// TODO: 在此处添加消息处理程序代码
MessageBox(_T(“Hi.”)); }
编译运行这个测试程序,点击控件位置就会弹出带有Hi.字样的MessageBox。 自定义事件
自定义事件与常用事件的区别在于,自定义事件不由 COleControl 类自动引发。自定义事件将控件开发人员确定的某一操作识别为事件。
添加常用事件的操作是在类视图中右击ActiveX 控件类,比如在此例中就是Caxtivexdemo1Ctrl。在菜单中选择添加事件,打开添加事件向导。定义一个叫做MyEvent的事件,事件可以带参数,比如我们加个BSTR的参数msg。
9
然后,回到类视图,这次选中库节点下的第三个节点,也就是_Dactivexdemo1Events,在下面就会看到新添加的这个事件。
再选中类视图中的控件类,即Cactivexdemo1Ctrl,下面也会出现一个MyEvent函数。
双击这个MyEvent可以看到定义代码如下: void MyEvent(BSTR msg) {
FireEvent(eventidMyEvent, EVENT_PARAM(VTS_PI1), msg); }
这里的这个MyEvent(BSTR msg)函数就是用于触发MyEvent事件用的,什么意思呢,就是说当在控件中需要出发自定义的这个MyEvent的时候调用这个MyEvent(BSTR msg)就可以了。下面结合例子看看是怎么回事。
10
比如说我们希望用户鼠标双击左键的时候触发这个事件,就这么来作。选中类视图中的控件类,即Cactivexdemo1Ctrl,然后在消息窗口中找到WM_LBUTTONDBCLK,添加这个消息的处理函数。
在消息处理函数中如下修改:
void Cactivexdemo1Ctrl::OnLButtonDblClk(UINT nFlags, CPoint point) {
// TODO: 在此添加消息处理程序代码和/或调用默认值 MyEvent(_T(“HI, MyEvent.”));
COleControl::OnLButtonDblClk(nFlags, point); }
这样每次用户在双击控件的时候就会触发我们自定义的MyEvent事件了。 然后看一下测试效果。
打开ActiveX控件测试容器,添加这个控件,然后双击控件,看消息框里出现什么了?
由于双击自然也就是两次单击,所以会同时出现两种事件。 activexdemo1 Control: MyEvent {msg=72} activexdemo1 Control: Click
打开测试项目,控件的控件事件里就多了一个MyEvent事件。
11
添加一个针对此事件的处理函数MyEventActivexdemo1ctrl1 (LPCTSTR msg),msg就是我们定义事件时的那个msg参数,在上面的定义中我们是传递了一个”HI, MyEvent.”字符串消息。现在看看是不是这个样子。在MyEventActivexdemo1ctrl1函数中我们显示一个MessageBox,把msg参数打印出来。
void CtestMFCDlg::MyEventActivexdemo1ctrl1(LPCTSTR msg) {
// TODO: 在此处添加消息处理程序代码 MessageBox(msg);
}
同时注意要把上面常用事件中定义的Click事件的处理函数ClickActivexdemo1ctrl1注释掉,然后编译运行程序后双击控件就会弹出HI, MyEvent.对话框。也就是说,由于双击操作触发了我们定义的MyEvent事件,进而调用MyEvent的处理函数。
12
因篇幅问题不能全部显示,请点此查看更多更全内容