实现属性表
属性表是ActiveX控件所特有的一种技术,可以在包容器程序处于设计阶段时为其提供一个可视化的人机交 互界面,并可以通过其对控件的自定义属性和库存属性进行设置。在用向导生成程序框架的同时即已经生成了一个空的用于管理自定义属性的属性页。在代码上通过 控件类实现文件中的属性页ID表对其进行维护:
这里的CSample68PropPage类是从COlePropertyPage派生出来的,而COlePropertyPage的基类又是 CDialog,因此不难发现CSample68PropPage与通常的对话框类是比较相似的。可以象处理对话框一样在资源视图中为缺省的属性页添加与 自定义属性相关的交互用控件,并通过ClassWizard将这些控件与类成员变量建立绑定关系。但是有一点不同,就是在绑定成员变量时还要与控件中的相 应属性建立起对应关系。如图12所示,在Optional property name组合框中输入自定义属性名或是直接从下拉列表选择库存属性名,ClassWizard向导将在属性页类的DoDataExchange()函数中 添加控件、变量和属性的绑定代码:
图12 成员变量、控件与属性的绑定
这里只是在向导生成的缺省属性页中实现了自定义属性的可视化设置。虽然也可以用相同的方法为库存属性进行设置,但是更多的还是采用添加库存属性页ID的 方法来直接使用库存属性页来对其进行维护。例如,对于库存属性BackColor和ForeColor,可以通过ID号为 CLSID_CcolorPropPage的库存属性页来进行设置,在将其添加到属性页ID表的同时一定要注意修改 BEGIN_PROPPAGEIDS()宏的属性页计数,否则将会引起系统的崩溃:
继续在ActiveX Control Test Container中测试控件,将其插入后选择"Edit"菜单的"Properties…"菜单项,将弹出入图13所示的属性表。该属性表共有三个属性 页,其中第一个属性页为刚才编辑的自定义属性页,第二个属性页(如图14所示)即为CLSID_CcolorPropPage所指定的颜色属性页(为库存 属性页),最后一个属性页则是向导自动添加的扩展属性页。在属性表中设置了相应的属性后,点击"应用"按钮即可让控件使用新的属性。这与在"Invoke Methods"对话框中所完成的功能一样,但显然要方便的多。而且在包容器程序的设计阶段,也是通过该属性表来完成控件与客户的属性设置交互的。
图13 控件的属性表
图14 颜色属性页
在包容程序中使用ActiveX控件
对于ActiveX控件的包容器程序,并不需要象使用OLE文档服务器或ActiveX文档服务器对象那样编写特定的包容器程序框架,直接将控件添加到工程并在对话框上创建即可对其进行使用。
通过"Project"菜单下的"Add To Project"菜单项弹出的"Components and Controls…"子菜单项打开一个"Components and Controls Gallery"对话框,进入到Registered ActiveX Controls目录下,选取前面创建的ActiveX控件,并将其添加到工程。向导将会在工程中添加一个关于此ActiveX控件的包装类,并 在"Controls"工具栏中添加一个表示此控件的图标。可以象使用其他的标准控件一样将其放置到对话框资源中,并修改其缺省属性。除此之外,还可以在 程序中通过对控件包装类成员函数的使用来动态更改控件的属性设置。例如,下面这段代码通过包装类对象m_ctrlTest在程序运行期间动态设置了控件的 XPos、YPos 以及Message属性:
图15 添加事件响应函数
在资源视图中用鼠标右键点击放置于对话框上的ActiveX控件,并从弹出菜单中选择"Events…"菜单项,将弹出如图15所示的对话框,在左边的 列表框中显示了控件提供的事件,双击事件将在包容器程序中添加相应的事件处理函数和事件映射表,并可以在响应控件发出的事件后进行相应的处理:
从上述对ActiveX控件的使用过程可以看出其与标准控件的使用并没有什么太大的区别,通过包装类使得在客户程序中对控件属性、方法的使用可以象使用普通MFC类一样简单。另外,在控件的包装类中还提供有Create()方法,使在程序运行期间也能够动态创建控件。
小结
尽管ActiveX控件从技术上集成了COM和OLE的许多精华技术,但由于MFC对ActiveX控件提供了强大的支持,使得对ActiveX控件的 开发成为一件非常容易的事情。但要深刻理解ActiveX控件技术,还要对一些基础技术有一个基本的概念,本文的目的并不在于介绍如何编写一个 ActiveX控件,而是通过对控件的创建过程的分析而使读者能够对ActiveX控件的开发有一个新的认识。本文所述代码在Windows 2000 Professional下由Microsoft Visual C++ 6.0编译通过。
属性表是ActiveX控件所特有的一种技术,可以在包容器程序处于设计阶段时为其提供一个可视化的人机交 互界面,并可以通过其对控件的自定义属性和库存属性进行设置。在用向导生成程序框架的同时即已经生成了一个空的用于管理自定义属性的属性页。在代码上通过 控件类实现文件中的属性页ID表对其进行维护:
BEGIN_PROPPAGEIDS(CSample68Ctrl, 1) PROPPAGEID(CSample68PropPage::guid) END_PROPPAGEIDS(CSample68Ctrl) |
这里的CSample68PropPage类是从COlePropertyPage派生出来的,而COlePropertyPage的基类又是 CDialog,因此不难发现CSample68PropPage与通常的对话框类是比较相似的。可以象处理对话框一样在资源视图中为缺省的属性页添加与 自定义属性相关的交互用控件,并通过ClassWizard将这些控件与类成员变量建立绑定关系。但是有一点不同,就是在绑定成员变量时还要与控件中的相 应属性建立起对应关系。如图12所示,在Optional property name组合框中输入自定义属性名或是直接从下拉列表选择库存属性名,ClassWizard向导将在属性页类的DoDataExchange()函数中 添加控件、变量和属性的绑定代码:
void CSample68PropPage::DoDataExchange(CDataExchange* pDX) { //{{AFX_DATA_MAP(CSample68PropPage) DDP_Text(pDX, IDC_MESSAGE, m_sMessage, _T("Message") ); DDX_Text(pDX, IDC_MESSAGE, m_sMessage); DDP_Text(pDX, IDC_TITLE, m_sCaption, _T("Caption") ); DDX_Text(pDX, IDC_TITLE, m_sCaption); DDP_Text(pDX, IDC_XPOS, m_nXPos, _T("XPos") ); DDX_Text(pDX, IDC_XPOS, m_nXPos); DDP_Text(pDX, IDC_YPOS, m_nYPos, _T("YPos") ); DDX_Text(pDX, IDC_YPOS, m_nYPos); //}}AFX_DATA_MAP DDP_PostProcessing(pDX); } |
图12 成员变量、控件与属性的绑定
这里只是在向导生成的缺省属性页中实现了自定义属性的可视化设置。虽然也可以用相同的方法为库存属性进行设置,但是更多的还是采用添加库存属性页ID的 方法来直接使用库存属性页来对其进行维护。例如,对于库存属性BackColor和ForeColor,可以通过ID号为 CLSID_CcolorPropPage的库存属性页来进行设置,在将其添加到属性页ID表的同时一定要注意修改 BEGIN_PROPPAGEIDS()宏的属性页计数,否则将会引起系统的崩溃:
BEGIN_PROPPAGEIDS(CSample68Ctrl, 2) PROPPAGEID(CSample68PropPage::guid) PROPPAGEID(CLSID_CColorPropPage) END_PROPPAGEIDS(CSample68Ctrl) |
继续在ActiveX Control Test Container中测试控件,将其插入后选择"Edit"菜单的"Properties…"菜单项,将弹出入图13所示的属性表。该属性表共有三个属性 页,其中第一个属性页为刚才编辑的自定义属性页,第二个属性页(如图14所示)即为CLSID_CcolorPropPage所指定的颜色属性页(为库存 属性页),最后一个属性页则是向导自动添加的扩展属性页。在属性表中设置了相应的属性后,点击"应用"按钮即可让控件使用新的属性。这与在"Invoke Methods"对话框中所完成的功能一样,但显然要方便的多。而且在包容器程序的设计阶段,也是通过该属性表来完成控件与客户的属性设置交互的。
图13 控件的属性表
图14 颜色属性页
在包容程序中使用ActiveX控件
对于ActiveX控件的包容器程序,并不需要象使用OLE文档服务器或ActiveX文档服务器对象那样编写特定的包容器程序框架,直接将控件添加到工程并在对话框上创建即可对其进行使用。
通过"Project"菜单下的"Add To Project"菜单项弹出的"Components and Controls…"子菜单项打开一个"Components and Controls Gallery"对话框,进入到Registered ActiveX Controls目录下,选取前面创建的ActiveX控件,并将其添加到工程。向导将会在工程中添加一个关于此ActiveX控件的包装类,并 在"Controls"工具栏中添加一个表示此控件的图标。可以象使用其他的标准控件一样将其放置到对话框资源中,并修改其缺省属性。除此之外,还可以在 程序中通过对控件包装类成员函数的使用来动态更改控件的属性设置。例如,下面这段代码通过包装类对象m_ctrlTest在程序运行期间动态设置了控件的 XPos、YPos 以及Message属性:
// 更新显示 UpdateData(); // 动态更改控件的Message属性 m_ctrlTest.SetMessage(m_sInput); // 设置显示坐标 m_ctrlTest.SetXPos(10); m_ctrlTest.SetYPos(10); |
图15 添加事件响应函数
在资源视图中用鼠标右键点击放置于对话框上的ActiveX控件,并从弹出菜单中选择"Events…"菜单项,将弹出如图15所示的对话框,在左边的 列表框中显示了控件提供的事件,双击事件将在包容器程序中添加相应的事件处理函数和事件映射表,并可以在响应控件发出的事件后进行相应的处理:
BEGIN_EVENTSINK_MAP(CSample69Dlg, CDialog) //{{AFX_EVENTSINK_MAP(CSample69Dlg) ON_EVENT(CSample69Dlg, IDC_SAMPLE68CTRL1, 1 /* MsgOut */, OnMsgOutSample68ctrl1, VTS_NONE) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() …… void CSample69Dlg::OnMsgOutSample68ctrl1() { // 得到输入字符数 int nNum = m_ctrlTest.MessageLen(); // 回显信息 m_sInput.Format("输入字符太多,共输入了%d个字符", nNum); // 显示信息 UpdateData(FALSE); } |
从上述对ActiveX控件的使用过程可以看出其与标准控件的使用并没有什么太大的区别,通过包装类使得在客户程序中对控件属性、方法的使用可以象使用普通MFC类一样简单。另外,在控件的包装类中还提供有Create()方法,使在程序运行期间也能够动态创建控件。
小结
尽管ActiveX控件从技术上集成了COM和OLE的许多精华技术,但由于MFC对ActiveX控件提供了强大的支持,使得对ActiveX控件的 开发成为一件非常容易的事情。但要深刻理解ActiveX控件技术,还要对一些基础技术有一个基本的概念,本文的目的并不在于介绍如何编写一个 ActiveX控件,而是通过对控件的创建过程的分析而使读者能够对ActiveX控件的开发有一个新的认识。本文所述代码在Windows 2000 Professional下由Microsoft Visual C++ 6.0编译通过。