【VS开发】ActiveX控件如何定制属性?

时间:2024-07-11 15:07:44

在很多场合下会存在这样的需求,那就是使用方在实际使用控件之前就想控件已经做了相应的处理比如加载的控件版本不正确等,或者需要在加载时才确定能够使用的功能集;这个时候传统的配置文件已经无法满足这种类型的需求了,往往的做法是在初始化控件的时候即做了相应的初始化,然后对自身的功能做了限制或者给使用方反馈,所以常常看到的是html标签中出现这样的写法:

  1. <OBJECT id="UsbossViewer" name="objocx"
  2. classid="clsid:6F82C754-6C31-43EA-9818-E95AD4E872FC"
  3. width="100%" height="250">
  4. <PARAM NAME="restrictedAgent" VALUE="1"/>
  5. Ming-WebReport viewer has not be installed properly.</OBJECT>

除了往常的初始化发现多了这一行:

  1. <PARAM NAME="restrictedAgent" VALUE="1"/>

这是什么呢?就是接下来要介绍的控件的自定义属性。

自定义属性与常用属性的区别在于,自定义属性未由 COleControl 类实现。自定义属性用于将 ActiveX 控件的某个状态或外观向使用该控件的程序员公开。

自定义属性有四种实现类型:“成员变量”、“带通知的成员变量”、“Get/Set 方法”和“参数化”。

  • “成员变量”实现

    这种实现将属性的状态表示为控件类中的成员变量。当对于控件而言,知道属性值何时更改并不重要时,使用“成员变量”实现。在这三种类型中,这种实现为属性创建的支持代码量最少。成员变量实现的调度映射项宏为 DISP_PROPERTY。

  • “带通知的成员变量”实现

    这种实现由一个成员变量和一个由“添加属性向导”创建的通知函数组成。属性值更改后,框架将自动调用这个通知函数。当需要在属性值更改后得到通知时,使用“带通知的成员变量”实现。由于这种实现需要调用一个函数,因此需要较长的时间。这种实现的调度映射项宏为 DISP_PROPERTY_NOTIFY。

  • “Get/Set 方法”实现

    这种实现由控件类中的一对成员函数组成。当控件用户请求属性的当前值时“Get/Set 方法”实现自动调用 Get 成员函数,而当控件用户请求更改属性值时自动调用 Set 成员函数。当需要在运行时计算属性值、在更改实际属性之前验证控件用户传递的值或实现只读或只写属性类型时,使用这种实现。这种实现的调度映射项宏为DISP_PROPERTY_EX。

  • “参数化”实现

    “添加属性向导”支持参数化实现。参数化属性(有时称为属性数组)可用于通过控件的单个属性访问一组值。这种实现的调度映射项宏为 DISP_PROPERTY_PARAM

下面介绍最常用的成员变量的实现,至于其它三种方式在以后会做介绍:

(1)首先加载控件的项目

(2)在“类视图”中展开控件的库节点

(3)右击控件的接口节点(库节点的第二个节点)打开快捷菜单

【VS开发】ActiveX控件如何定制属性?

【VS开发】ActiveX控件如何定制属性?

(4)单击“添加属性”进入属性向导

命名属性名,选择类型,此外的名字会自动生成

【VS开发】ActiveX控件如何定制属性?

(5)单击完成,这时会在Idl文件自动生成相应的属性

【VS开发】ActiveX控件如何定制属性?

同时自动生成相应的成员变量

【VS开发】ActiveX控件如何定制属性?

(6)这个时候就可以使用这个变量了,在按照文章开头的方式传入值,咦~~你会发现初始化的属性并没有传入到该成员变量中,并没有达到预期的效果,为什么呢?

原因很简单,就是没有做属性的持久化,关于这个关键的详细解释这里就不做展开了,你要做的是是在Ctrl文件中DoPropExchange方法调用PX_方法:

  1. void CCCEACtrl::DoPropExchange(CPropExchange* pPX)
  2. {
  3. ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  4. COleControl::DoPropExchange(pPX);
  5. // TODO: 为每个持久的自定义属性调用 PX_ 函数。
  6. PX_String(pPX, "restrictedAgent", m_restrictedAgent, "0");
  7. PX_String(pPX, "GetLoginInterfaceID", m_GetLoginInterfaceID, "0");
  8. }

这时最基础的属性框架已经OK了,该属性可以正常地使用了。