孙鑫VC视频教程笔记之第十八课“ActiveX控件”

来源:互联网 发布:梦想海贼王活动数据 编辑:程序博客网 时间:2024/04/30 14:37

1.      容器:可以在其上拖放ActiveX控件,如VB调用MFC编写的ActiveX控件时候,VB就是一个容器。

2.      MFC通过ClassWizard创建的工程有以下模块:
CApp
:应用程序类
CCtrl
:相当于单文档的程序中CView类,主要对窗口的操作在这个类中完成。
CPropPage
:控件的属性页
接口(Interface):它是一个抽象基类,其中写的方法都是虚函数,所有虚函数的实现放在CCtrl中。外部程序调用接口中方法,其实际调用的就是CCtrl中实现的类。接口底层实现的细节是由COM的技术实现的,MFC对其进行了封装。

3.      ActiveX控件的调试工具:VC的安装目录下有一个程序TSTCON32.EXE

4.      控件的注册的通用方法是Regsvr32,其实这个程序也是调用控件内部的DllRegisterServer方法实现对控件中的信息添加到注册表中。反注册函数DllUnregisterServer的原理也是有的。这两个函数在创建的工程下Globals

5.      ActiveX控件的四种属性:

Ø         Stock:为每个控件提供的标准属性,如字体或颜色。详细信息详细信息学习型详细信息详细信息                   

Ø         Ambient:围绕控件的环境属性——已被置入容器的属性。这些属性不能被更改,但控件可以使用它们调整自己的属性。

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

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

6.      如果当前调试目录下的Activex控件被其它程序在使用的状态下的话,再次编译该ActiveX控件程序将出现无法对控件进行写入的错误。所以再次在VC中调试该控件的时候,一定要确保该目录下的控件没有被别的程序(像VB)所添加为控件。

7.      为控件添加系统属性(需要在其它IDE中有相应设置的属性设置框,如在VB中的右侧属性就是):classwizard->automation。在classname中选择CCtrl类,然后点击add property按钮添加属性。

本例中一设置控件的背景色和文字的前景色举例:

a.      按上述所说的方法添加BackColorForeColor属性

b.      CCtrlOnDraw函数中添加如下代码:

CBrush brush(TranslateColor(GetBackColor())); //得到用户选择的背景颜色,将它设置为画刷的颜色

      pdc->FillRect(rcBounds,&brush);

      pdc->SetBkMode(TRANSPARENT); //将文字的背景设置成透明的

      //pdc->SetBkColor(); //设置文本的背景颜色

     

pdc->SetTextColor(TranslateColor(GetForeColor())); //得到用户选择的前景色,并将之设置字体的前景色

注:ActiveX控件的调试也可以放在VB中进行,像设置前景色,背景色之类的操作比较方便。方法为在VB的左侧控件面板上右键选择添加部件。

8.      在属性页中添加系统属性(以添加颜色属性页为例):

CCtrl源文件中找到如下的宏代码:

BEGIN_PROPPAGEIDS(CClockCtrl, 1)

            PROPPAGEID(CClockPropPage::guid)

END_PROPPAGEIDS(CClockCtrl)

      说明:guid是一个全局的唯一标识符号,是一个128位的整数,用来唯一的标识一个组件或接口。

      添加代码:PROPPAGEID(CLSID_CColorPropPage) //添加颜色属性页面,其中CLSID_CColorPropPage为颜色属性页的全局唯一标识符

      BEGIN_PROPPAGEIDS1改为2注意:如果添加了属性页,一定要将属性页的数量随之增加。(添加颜色属性页后,在VB中调用的时候,将控件拖动到窗口上上也是成功的,但点击右键属性的时候,显示类没有注册,查找具有CLSID的对象”这样一个错误,但将程序release后发现在别的MFC程序中调用没有发生问题。

9.      添加自定义属性:在此处以修改时钟的时间间隔为例。步骤为classwizard->automation,在classname中选择CCtrl类,然后点击add property按钮添加属性。在External Name中添加属性名称Interval,这个名称就是在其它编译环境中控件所拥有的属性;类型选择shortVariable Name为在CCtrl源文件中创建的成员变量;Notification function为通知函数,即用户修改属性后,对应的成员变量会拿到这个值,然后就可以在这个通知函数将处理了。

通知函数中的代码如下:

if(m_interval<0 || m_interval>6000)

      {

           m_interval=1000;

      }

      else

      {

           m_interval=m_interval/1000*1000; //取整

           KillTimer(1); //将老的Timer关闭

           SetTimer(1,m_interval,NULL);

}

 VC编译环境自带的ActiveX控件测试容器对自定义属性进行测试:

a.      添加ActiveX控件

b.      选择菜单:control->invoke methods(调用方法)->method name下拉式列表中选择对应的属性值,其中分为得到属性值,则选择PropGet,设置属性值,则选择PropSet,在Parameter中填写我们想使用的属性值,点击set value按钮,在点击Invoke按钮

10. 在属性页中添加自定义属性设置:

还是以上述时间的间隔举例。在对话框资源中在属性对话框上添加文本框,此用来接收用户输入的间隔时间,给此文本框添加成员变量,在添加成员对话框的最下方有个下拉列表:optional property name,在这里填写属性的外部名称,Interval,即可,该过程不需要写一行代码即可实现。(在实际例子中点击控件右键属性的时候发生一个致命错误,点击忽略,发现结果还是正确的)

11. 给控件添加方法:

classwizard->Automation->Add Method->External Name(外部被调用时候所使用的名称),向导会自动在CCtrl添加相应的方法,在其中实现就可以了。

调试方法是采用自带的ActiveX控件测试容器,control->invoke methods(调用方法)->method name下拉式列表中选择对应方法名称,点击Invoke即可。

12. 给控件添加事件:

事件分为系统标准事件(如click等)和自定义事件。

ClassView中右键点击_DClockEvents,选择添加事件,或者用ClassWinzard对话框上选择ActiveX Event也可。添加完成后双击_DClockEvents,进入源代码,发现两个接口之间的区别:

[default] dispinterface _DClock;

[default, source] dispinterface _DClockEvents;

事件前面多了一个source,这表明事件是一个源接口,这表明控件将用这个源接口向容器来发送通知事件,这个接口中实现的代码需要用户在容器上编写,而不是在控件内部。

a.      标准事件:

ClassView中右键点击_DClockEvents,选择添加事件,在Add Event对话框上选择External Name下拉列表,选择标准事件,如click,这样就完成了对已存储事件的创建。

调试方法可以在VB窗体中添加控件,双击按钮,选择事件下拉选择列表,发现click事件,在其中添加想实现的内容就可以了。

b.      自定义事件
ClassView中右键点击_DClockEvents,选择添加事件,在Add Event对话框上选择External Name,填写自己想创建的外部使用的事件名称。创建完成后发现CCtrl的类视图中添加了一个事件映射:FireEventNameeventname为自定义事件的外部名称)。然后在想触发该事件的地方调用FireEventName,以此通知容器中的控件相应的事件可以被触发了,然后用户可以在容器中编写相应的代码。

13. 控件上子定义属性设置的长期有效性:

对于自定义属性值,如果在VB程序中设置好了值后,关闭工程,当再次打开工程的时候,发现原先设置好的属性值没有被保存下来。

CCtrl类中的DoPropExchange方法中提供了属性值保存的长期有效性,在其中可以调用以PX打头大方法让用户自定义的属性值长期有效。调用哪种PX打头的方法取决于自定义属性所对应的内部成员变量的类型,这里以PX_SHORT举例,第一个参数是DoPropExchange方法中参数指针,第二个参数是属性的外部名称,第三个是属性所对应的内部成员变量名称。第四个是属性的默认填充值。

还有一个问题,对于自定义的属性,发现如果在属性页中对属性值进行了修改,但在容器的对应属性框中该值没有相应的改变,但系统属性是可以的。在属性通知方法OnIntervalChanged内调用BoundPropertyChanged方法即可,参数是属性ID,可以在类视图中双击属性名称即可看到(id(XXX)XXX即为属性ID)。

14.  检测容器的环境属性:

检测控件是在容器的运行模式还是在设计模式下可调用方法:AmbientUserMode关于ActiveX的详细学习可以参考MSDNCOleControl页,点击页面下方的ActiveX链接。

15. VC调用ActiveX控件:

方法一:直接在对话框上右键选择Insert ActiveX Control

方法二:菜单project->add to project->component and controls,选择已经注册的ActiveX控件。向导会自动添加一个关于控件的类,在该类中有ActiveX控件定义好的属性和方法,它Create方法可以动态创建一个ActiveX控件,其操作过程很动态创建button很类似。至于给控件添加事件,可以在控件上右键选择Event即可。