COM 组件设计与应用18属性包.docx

上传人:b****5 文档编号:7962731 上传时间:2023-01-27 格式:DOCX 页数:11 大小:266.11KB
下载 相关 举报
COM 组件设计与应用18属性包.docx_第1页
第1页 / 共11页
COM 组件设计与应用18属性包.docx_第2页
第2页 / 共11页
COM 组件设计与应用18属性包.docx_第3页
第3页 / 共11页
COM 组件设计与应用18属性包.docx_第4页
第4页 / 共11页
COM 组件设计与应用18属性包.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

COM 组件设计与应用18属性包.docx

《COM 组件设计与应用18属性包.docx》由会员分享,可在线阅读,更多相关《COM 组件设计与应用18属性包.docx(11页珍藏版)》请在冰豆网上搜索。

COM 组件设计与应用18属性包.docx

COM组件设计与应用18属性包

COM组件设计与应用(十八)——属性包

作者:

杨老师

下载源代码

一、前言

  书接上回,本回着落在介绍属性包IPersistPropertyBag接口的实现方法和调用方式。

属性包,是以“名称-值”的方式提供组件持续性的支持,而“名称-值”恰恰又适合于用文本方式来表现。

下面的片段是在HTML中插入MicrosoftMonthViewControlActiveX控件后的样式:

232E456A-87C3-11D1-8BE3-0000F8754DA1"id="MonthView1">

以文本方式保存组件属性,比较直观、容易修改,上面HTML示例中的就很清晰。

下面开始介绍如何在组件中实现IPersistPropertyBag接口。

二、组件的实现

(1)vc6.0开发步骤

1、建立一个工作空间(WorkSpace)。

2、在这个工作空间中,建立ATL工程,示例程序工程为Simple18。

3、增加ATL对象类,默认全部选项。

示例程序中的ATL对象短名称是Property。

4、增加一些属性。

在以前的章回中,我们只介绍了增加接口函数的方法,由于今天是首次增加接口属性,所以稍微细致一些。

步骤是,在ClassView卡片中选择接口(IProperty)后,执行鼠标右键菜单"AddProperty..."

5、增加BSTR类型的接口属性str,同样的方式,再增加一个long型的接口属性interger。

在示例程序中,这两个属性其实只为演示,并没有实际的意义。

6、接口中的属性,多数情况下会对应对象内部的一个成员变量,因此我们现在要添加成员变量。

选择对象类名,执行鼠标右键菜单"AddMemberVariable...."

7、添加两个成员变量,一个是CComBSTRm_str对应于接口属性str;另一个是longm_integer对应于接口属性integer。

(2)开发步骤

1、建立一个空白解决方案。

2、在解决方案中,新增ATL项目。

示例程序中项目名称叫Simple18,注意不要选择“属性化编程”方式。

3、添加ATL类。

选择“ATL的简单对象”。

默认全部选项。

示例程序中ATL类短名称为Property,类名称为CMyProperty。

(注1)

4、增加一些属性。

在以前的章回中,我们只介绍了增加接口函数的方法,由于今天是首次增加接口属性,所以稍微细致一些。

步骤是,在类视图卡片中选择接口(IProperty)后,执行鼠标右键菜单"添加属性..."

5、增加BSTR类型的接口属性str,同样的方式,再增加一个long型的接口属性interger。

在示例程序中,这两个属性其实只为演示,并没有实际的意义。

6、接口中的属性,多数情况下会对应对象内部的一个成员变量,因此我们现在要添加成员变量。

选择对象类名,执行鼠标右键菜单"添加变量...."

7、添加两个成员变量,一个是CComBSTRm_str对应于接口属性str;另一个是longm_integer对应于接口属性integer。

(3)实现代码

  至此,我们组件的框架已经完成,下面该完成函数函数的实现了:

STDMETHODIMPCxxx:

:

get_str(BSTR*pVal)

{

*pVal=m_str.Copy();

returnS_OK;

}

STDMETHODIMPCxxx:

:

put_str(BSTRnewVal)

{

m_str=newVal;

returnS_OK;

}

STDMETHODIMPCxxx:

:

get_integer(LONG*pVal)

{

*pVal=m_integer;

returnS_OK;

}

STDMETHODIMPCxxx:

:

put_integer(LONGnewVal)

{

m_integer=newVal;

returnS_OK;

}

没有什么复杂的,就是实现str、integer两个属性值的设置和读取功能。

(4)添加IPersistPropertyBag接口

  还记得我们在上回书中如何添加IPersistStreamInit的吗?

添加IPersistPropertyBag的方法也一样,但这次我们换一个方式,即我们不从IPersistPropertyBag派生,而是从IPersistPropertyBagImpl<>派生。

在ATL中,系统帮我们已经完成了很多接口的默认实现,我们只要从IxxxImpl<>派生,然后再添加一些必要的映射和变量,就可以了。

这样显然要比自己去实现接口的所有函数要简单许多了。

其实,如果你明白了本回IPersistPropertyBagImpl<>派生的方法后,你完全可以修改前回书中的实现方法,从IPersistStreamInit派生改进为从IPersistStreamInitImpl<>派生。

classATL_NO_VTABLECxxx:

publicCComObjectRootEx<...>,

publicCComCoClass<...>,

publicIDispatchImpl<...>,

publicIPersistPropertyBagImpl//手工添加派生类

{

.........

BEGIN_COM_MAP(Cxxx)

.........

COM_INTERFACE_ENTRY(IPersistPropertyBag)//手工添加接口表

END_COM_MAP()

.........

//手工添加属性映射表,这是IPersistXXXImpl所必须的。

//将来你在写ActiveX的时候,ATL向导会帮我们添加属性映射表

BEGIN_PROP_MAP(Cxxx)

//参数:

"属性名称",接口属性序号(见IDL文件),属性页对话窗

PROP_ENTRY("str",1,CLSID_NULL)

PROP_ENTRY("integer",2,CLSID_NULL)

END_PROP_MAP()

.........

public:

.........

//这个成员变量,是IPersistXXXImpl所必须的

boolm_bRequiresSave;//表示属性数据是否已经改变而需要保存

};

  我们只要手工添加以上内容,而不用自己写任何IPersistPropertyBag接口的函数,多简单呀!

天空出彩霞呀,地上开红花呀......会唱这只歌的同学请举手,每个人奖励vckbase的专家分500!

三、调用者的实现

  我们在阅读MSDN关于IPersistPropertyBag接口函数的时候,你会发现还需要一个接口IPropertyBag与之配合才能实现属性包功能。

而IPropertyBag则需要我们在调用者(容器)中来实现该接口。

它们之间的关系如下:

  前面几回书中,我们已经学会了从IUnknown派生类,也学会了从IDispatch派生类,也学会了从ICallBack派生类......同样,这回我们要从IPropertyBag派生了。

在示例程序中,我们添加了一个类CPropertyBag:

:

publicIPropertyBag,同时重载了所有的虚函数。

STDMETHODIMPCPropertyBag:

:

QueryInterface(conststruct_GUID&iid,void**ppv)

{

*ppv=this;

returnS_OK;

}

ULONG__stdcallCPropertyBag:

:

AddRef(void)

{return1;}//做个假的就可以,因为反正这个对象在程序结束前是不会退出的

ULONG__stdcallCPropertyBag:

:

Release(void)

{return0;}//做个假的就可以,因为反正这个对象在程序结束前是不会退出的

STDMETHODIMPCPropertyBag:

:

Read(LPCOLESTRpszPropName,VARIANT*pVar,IErrorLog*pErrorLog)

{

//根据pszPropName指定的属性名称,你要提供该属性的值。

//而值的数据类型已经在pVal->vt中指定了。

if(如果能提供指定的数据)returnS_OK;

elsereturnE_FAIL;

}

STDMETHODIMPCPropertyBag:

:

Write(LPCOLESTRpszPropName,VARIANT*pVar)

{

//根据psaPropName指定的属性名称和pVar提供的值

//你保存到文本中去吧。

returnS_OK;

}

  以上是调用者(容器)程序的关键部分,其它的管理和协调部分,读者去阅读示例程序代码。

编译注册组件,并运行调用者示例程序,显示如下:

  在编辑窗口中你可以随便指定str和interger的值,然后“启动组件”,那么你设定的属性值就会在启动组件的同时,通过IPersistPropertyBag接口设置到组件中(还原了持续性的环境)。

而后,你就可以在下面的Property分组操作中,“设置/读取”组件的属性了。

当“关闭组件”的时候,程序通过调用IPersistPropertyBag接口函数,又重新取得组件的属性名称和值保存到编辑窗的文本中了。

四、小结

  理解了本回属性包接口的功能,你就能体会出IE是如何装载ActiveX(注2)控件并设置控件的状态了。

注1:

在中,由于系统已经有CProperty类,所以这里我们改换名称为CMyProperty。

注2:

通过十八回的学习,我们已经了解组件的一些常用接口,为我们学习ActiveX的组件编程打下了基础。

下回书,我们就开始学习ActiveX。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1