2022年COM组件教程 .pdf
步骤 1:创建项目Visual Studio .NET 2003本教程将带领您逐步骤通过一个非属性化ATL 项目,该项目创建一个显示多边形的ActiveX 对象。此对象包括使用户得以更改组成多边形的边数的选项以及刷新显示的代码。注意 本教程创建与Polygon (多边形)示例相同的源代码。如果您希望避免手动输入源代码,则可以从多边形示例摘要 下载源代码。然后,您可以一边参考Polygon 源代码一边阅读教程,或者用它来检查自己的项目中是否有错误。使用“ATL 项目向导 ” 创建初始ATL 项目1.在 Visual Studio 开发环境中,在 “ 文件” 菜单上单击 “ 新建 ” ,然后单击 “ 项目” 。2.单击“ Visual C+ 项目” 文件夹并选择 “ ATL 项目 ” 。3.键入Polygon作为项目名称:源代码的位置通常默认为Visual Studio Projects ,并且将自动创建一个新文件夹。4.单击“ 确定 ” ,“ ATL 项目向导 ” 随即打开。5.单击“ 应用程序设置 ” 以查看可用选项:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 21 页 - - - - - - - - - 6.在创建控件时,如果控件必须是进程内服务器,则将“ 服务器类型 ” 保留为DLL。7.本教程中将不使用属性,因此请确保没有选中“ 属性化 ” 复选框。8.将其他选项保留在它们的默认值,然后单击“ 完成” 。“ ATL 项目向导 ” 将通过生成若干个文件来创建项目。可以通过展开Polygon 对象在解决方案资源管理器中查看这些文件。下面列出了这些文件。文件说明Polygon.cpp 包含 DllMain 、DllCanUnloadNow、DllGetClassObject、DllRegisterServer和 DllUnregisterServer的实现。还包含对象映射,该映射是项目中ATL 对象的列表。它最初是空白的。Polygon.def 此模块定义文件为链接器提供有关DLL 所需的导出的信息。Polygon.idl 接口定义语言文件,描述特定于对象的接口。Polygon.rgs 此注册表脚本包含用于注册程序的DLL 的信息。Polygon.rc 资源文件,最初包含版本信息和含有项目名称的字符串。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 21 页 - - - - - - - - - Resource.h 资源文件的头文件。Polygonps.def 此模块定义文件为链接器提供有关代理所需的导出和支持跨单元调用的存根(stub) 代码的信息。有关详细信息,请参见COM+ 单元模型。stdafx.cpp 将包括(#include ) ATL 实现文件的文件。stdafx.h 将包括(#include ) ATL 头文件的文件。在下一步骤中,您将向项目添加控件。步骤 2:添加控件Visual Studio .NET 2003在此步骤中,您将向项目添加控件,生成此控件,并在Web 页中对其进行测试。向 ATL 项目添加对象1.在“ 类视图 ” 中,右击 “ Polygon”项目。2.指向快捷菜单上的 “ 添加” ,然后单击 “ 添加类 ” 。即会出现 “ 添加类 ” 对话框。左侧的树结构中列出了不同的对象类别:3.展开树结构并单击 “ ATL”文件夹。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 21 页 - - - - - - - - - 4.从右侧的模板列表选择“ ATL 控件 ” 。 单击“ 打开 ” 。 “ ATL 控件向导 ” 将打开,从中可以配置控件:5.键入PolyCtl作为简称,并注意其他字段将自动完成。先不要单击“ 完成 ” ,因为需要做一些更改。“ ATL 控件向导 ” 的“ 名称 ” 页包含以下字段:字段内容简称为控件输入的名称。类为了实现控件而创建的C+ 类名。.h 文件为了包含C+ 类的定义而创建的文件。.cpp 文件为了包含C+ 类的实现而创建的文件。CoClass此控件的组件类的名称。接口接口的名称,控件将在此接口上实现它的自定义方法和属性。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 21 页 - - - - - - - - - 类型对控件的说明。ProgID可用于查找控件的CLSID 的可读名称。需要在 “ATL 控件向导 ” 中另外进行几个设置。启用对多格式错误信息和连接点的支持1.单击“ 选项 ” 打开 “ 选项 ” 页。2.选择“ 连接点 ” 复选框。这将创建对IDL 文件中输出接口的支持。还可以使控件成为可插入的, 这意味着它可以嵌入到支持嵌入对象的应用程序中,如 Excel 或 Word 。使控件成为可插入的1. 单击“ 外观 ” 打开 “ 外观 ” 页。2. 选择“ 可插入 ” 复选框,默认情况下该复选框会被清除。对象显示的多边形将具有纯填充颜色,因此需要添加“ 填充颜色 ” 常用属性。添加“ 填充颜色 ” 常用属性并创建控件1.单击“ 常用属性 ” 打开“ 常用属性 ” 页。2.在“ 不支持 ” 下,向下滚动可能常用属性的列表。双击“ Fill Color”以将其移动到 “ 支持 ” 列表:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 21 页 - - - - - - - - - 3.这将完成控件的选项。单击“ 完成” 。在向导创建控件时,有若干代码改变了并添加了一些文件。创建了以下文件:文件说明PolyCtl.h 包含 C+ 类CPolyCtl的大部分实现。PolyCtl.cpp 包含CPolyCtl的其余部分。PolyCtl.rgs 一个文本文件,包含用于注册控件的注册表脚本。PolyCtl.htm 一个 Web 页,包含对新创建的控件的引用。向导还执行了以下代码更改:向 stdafx.h 和 stdafx.cpp 文件添加了#include语句,以包含支持控件所必需的ATL 文件。更改了 Polygon.idl 以包含新控件的详细信息。将新控件添加到了Polygon.cpp 中的对象映射。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 21 页 - - - - - - - - - 现在可以生成控件,查看它的运行情况。生成和测试控件生成和测试控件1.在“ 生成 ” 菜单上单击 “ 生成 Polygon”。2.控件完成了生成后,在解决方案资源管理器中双击PolyCtl.htm 。将显示包含控件的HTML Web 页。您应看到一个矩形和文本ATL 7.0 : PolyCtl。这便是您的控件。注意 当完成本教程时,如果收到DLL 文件无法创建的错误信息, 请关闭 PolyCtl.htm 文件和 “ActiveX 控件测试 ” 容器并重新生成解决方案。如果仍无法创建DLL,请重新启动计算机或注销(如果您使用的是“ 终端服务 ” ) 。下一步,您将向控件添加自定义属性。步骤 3:向控件添加属性Visual Studio .NET 2003IPolyCtl是包含控件的自定义方法和属性的接口,您将在其中添加属性。使用“ 添加属性向导 ” 添加属性1.在“ 类视图 ” 中右击IPolyCtl(展开 “ Polygon”分支找到它)。2.在快捷菜单上单击 “ 添加” ,然后单击 “ 添加属性 ” 。“ 添加属性向导 ” 随即出现。3.在属性类型的下拉列表中,选择“ short”。4.键入Sides作为属性名:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 21 页 - - - - - - - - - 5.单击“ 完成 ” 完成属性的添加。将属性添加到接口时,MIDL(编译 .idl 文件的程序)定义检索其值的Get方法和设置新值的Put方法。这些方法的命名方式是在属性名的前面加上put_和get_。“ 添加属性向导 ” 将必需的行添加到 .idl 文件。它还将Get和Put函数原型添加到PolyCtl.h 中的类定义,并将一个空实现添加到PolyCtl.cpp 。 您可以通过打开PolyCtl.cpp 并查找函数get_Sides和put_Sides来进行检查。虽然现在有了设置和检索属性的主干函数,但需要有地方存储属性。您将创建存储属性的变量,并相应地更新函数。创建存储属性的变量并更新put 和 get 方法1.从解决方案资源管理器中,打开PolyCtl.h 并在类定义末尾的m_clrFillColor定义后添加下行:复制short m_nSides; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 21 页 - - - - - - - - - 2.设置m_nSides的默认值。向 PolyCtl.h 中的构造函数添加一行, 使默认形状成为三角形:复制CPolyCtl() m_nSides = 3; 3.实现Get和Put方法。get_Sides和put_Sides函数声明已经添加到PolyCtl.h 。将以下代码添加到PolyCtl.cpp 以完成这两个方法:复制STDMETHODIMP CPolyCtl:get_Sides(short *pVal) *pVal = m_nSides; return S_OK; STDMETHODIMP CPolyCtl:put_Sides(short newVal) if (newVal 2 & newVal 101) m_nSides = newVal; return S_OK; else return Error(_T(Shape must have between 3 and 100 sides); get_Sides方法通过pVal指针返回Sides属性的当前值。在put_Sides方法中,代码确保用户将Sides属性设置为可接受的值。最小值必须是2,而且由于对每个边都要使用一系列点,100 是合理的最大值限制。您现在有了一个名为Sides的属性。下一步,您将更改绘图代码以便使用它。步骤 5:添加事件Visual Studio .NET 2003在此步骤中, 您将把ClickIn和ClickOut事件添加到ATL 控件。如果用户在多边形的内部单击,将激发ClickIn事件;如果用户在外部单击,将激发ClickOut。添加事件的任务如下:添加ClickIn和ClickOut方法名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 21 页 - - - - - - - - - 生成类型库实现连接点接口添加 ClickIn 和 ClickOut 方法您在第 2 步中创建ATL 控件时,选择了 “ 连接点 ” 复选框。这在Polygon.idl 文件中创建了_IPolyCtlEvents接口。请注意,接口名称以下划线开头。 此约定指示该接口是内部接口。这样,允许浏览COM 对象的程序便可以选择不将此接口显示给用户。还请注意,选择“ 连接点 ” 时在Polygon.idl 文件中添加了下面的行,指示_IPolyCtlEvents 是默认源接口:default, source dispinterface _IPolyCtlEvents;源属性指示控件为通知的源,因此它将对容器调用此接口。现在将ClickIn和ClickOut方法添加到_IPolyCtlEvents接口。添加 ClickIn 和 ClickOut 方法1.在“ 类视图 ” 中,展开Polygon 和 PolygonLib 以显示_IPolyCtlEvents。2.右击 _IPolyCtlEvents。在快捷菜单上单击“ 添加” ,然后单击 “ 添加方法 ” 。3.选择void作为 “ 返回类型 ” 。4.在“ 方法名称 ” 框中输入ClickIn。5.在“ 参数属性 ” 下,选中 “ in ”框。6.选择“ LONG” 作为“ 参数类型 ” 。7.键入x作为参数名,然后单击“ 添加 ” 。8.重复第 5 步到第7 步,这次键入y作为参数名。9.单击“ 完成 ” 。10. 重复以上步骤,用相同的LONG参数x和y,相同的 “ 参数属性 ” 和相同的void返回类型定义ClickOut方法。检查 Polygon.idl 文件,查看代码是否添加到了_IPolyCtlEvents调度接口。Polygon.idl 文件中的_IPolyCtlEvents调度接口现在看起来应像这样:复制dispinterface _IPolyCtlEvents properties: methods: id(1), helpstring(method ClickIn) void ClickIn(inLONG x, in LONG y); id(2), helpstring(method ClickOut) void ClickOut(in LONG x, in LONG y); ; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 21 页 - - - - - - - - - ClickIn和ClickOut方法接受单击点的x 和 y 坐标作为参数。生成类型库现在请生成类型库,因为“ 连接点向导 ” 将用它来获取构造控件的连接点接口和连接点容器接口所需的信息。生成类型库重新生成项目。- 或 - 在“ 解决方案资源管理器 ” 中右击Polygon.idl 文件,并在快捷菜单上单击“ 编译 ” 。这将创建Polygon.tlb 文件, 它就是您的类型库。 从解决方案资源管理器中看不见Polygon.tlb 文件,因为它是二进制文件,无法直接查看和编辑。实现连接点接口为您的控件实现一个连接点接口和一个连接点容器接口。在 COM 中,事件通过连接点机制来实现。为了从 COM 对象接收事件,容器建立一个到COM 对象实现的连接点的报告连接。由于COM 对象可以有多个连接点,COM 对象还实现连接点容器接口。通过该接口,容器可以确定哪些连接点受支持。实现连接点的接口称为IConnectionPoint,实现连接点容器的接口称为IConnectionPointContainer。为了帮助实现IConnectionPoint,您将使用 “ 实现连接点向导 ” 。该向导通过读取类型库并为每个可以激发的事件实现函数来生成IConnectionPoint接口。使用“ 实现连接点向导 ”1.在“ 类视图 ” 中,右击控件的实现类CPolyCtl。2.在快捷菜单上单击 “ 添加” ,然后单击 “ 添加连接点 ” 。3.从“ 源接口 ” 列表中选择 “ _IPolyCtlEvents”并双击它,以将它添加到 “ 实现连接点 ” 列。单击“ 完成” 。将生成连接点的代理类,这里是指CProxy_IPolyCtlEvents。如果在解决方案资源管理器中查看生成的_IPolyCtlEvents_CP.h 文件,则将看到它包含一个名为CProxy_IPolyCtlEvents的类,该类是从IConnectionPointImpl派生的。_IPolyCtlEvents_CP.h 还定义了两个方法Fire_ClickIn和Fire_ClickOut,它们接受两个坐标参数。当您需要从控件中激发事件时,将调用这些方法。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 21 页 - - - - - - - - - 向导还将CProxy_PolyEvents和IConnectionPointContainerImpl添加到了控件的多重继承列表。向导还通过将适当的项添加到COM 映射,为您公开了IConnectionPointContainer。您已完成了实现支持事件的代码。现在,添加一些代码以在适当的时候激发事件。记住,当用户在控件中单击左鼠标按钮时,您将激发ClickIn或ClickOut事件。若要了解用户何时单击按钮,请添加 WM_LBUTTONDOWN消息的处理程序。为 WM_LBUTTONDOWN 消息添加处理程序1.在“ 类视图 ” 中,右击CPolyCtl 类,并在快捷菜单上单击“ 属性” 。2.在“ 属性 ” 窗口中,单击 “ 消息” 图标,然后从左边的列表中单击“ WM_LBUTTONDOWN ” 。3.从出现的下拉列表中,单击“ OnLButtonDown”。OnLButtonDown处理程序声明将添加到PolyCtl.h 中,处理程序实现将添加到PolyCtl.cpp 中。接下来修改该处理程序。修改 OnLButtonDown 方法更改 PolyCtl.cpp 中包含OnLButtonDown方法的代码(删除向导所放置的任何代码),使它看起来像这样:复制LRESULT CPolyCtl:OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) HRGN hRgn; WORD xPos = LOWORD(lParam); / horizontal position of cursor WORD yPos = HIWORD(lParam); / vertical position of cursor CalcPoints(m_rcPos); / Create a region from our list of points hRgn = CreatePolygonRgn(&m_arrPoint0, m_nSides, WINDING); / If the clicked point is in our polygon then fire the ClickIn / event otherwise we fire the ClickOut event if (PtInRegion(hRgn, xPos, yPos) Fire_ClickIn(xPos, yPos); else Fire_ClickOut(xPos, yPos); / Delete the region that we created DeleteObject(hRgn); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 21 页 - - - - - - - - - return 0; 此代码利用在OnDraw函数中计算的点创建一个区域,以通过调用PtInRegion来检测用户的鼠标单击。uMsg参数是所处理的Windows 消息的ID。这使您可以有一个处理消息范围的函数。wParam和lParam参数是所处理消息的标准值。参数bHandled使您得以指定函数是否处理了消息。默认情况下,值设置为TRUE,指示函数处理了消息,但也可以将其设置为FALSE。这将使ATL 继续查找要将消息发送到的其他消息处理程序函数。生成和测试控件现在尝试您的事件。生成控件并再次启动“ActiveX 控件测试容器 ” 。这次查看事件日志窗口。若要将事件路由到输出窗口,请从“ 选项” 菜单中单击 “ 记录 ” ,然后选择 “ 记录到输出窗口 ” 。插入控件并试着在窗口中单击。请注意,在填充多边形的内部单击将激发ClickIn,在它的外部单击将激发ClickOut。接下来将添加属性页。步骤 6:添加属性页Visual Studio .NET 2003属性页作为单独的COM 对象实现,这使得可以在需要时共享属性页。在此步骤中,您将执行以下任务以将属性页添加到控件:创建属性页资源添加用来创建和管理属性页的代码向控件添加属性页创建属性页资源若要将属性页添加到控件,请使用“ATL 添加类向导 ” 。添加属性页1.在解决方案资源管理器中,右击“ Polygon”。2.在快捷菜单上单击 “ 添加” ,然后单击 “ 添加类 ” 。3.从模板列表中,选择“ ATL 属性页 ” 并单击 “ 打开 ” 。4.当“ ATL 属性页向导 ” 出现时,输入PolyProp作为简称:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 21 页 - - - - - - - - - 5.单击“ 字符串 ” 打开 “ 字符串 ” 页,然后输入&Polygon作为标题:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 21 页 - - - - - - - - - 属性页的 “ 标题” 是在该页的选项卡中出现的字符串。“ 文档字符串 ” 是属性框架用来放在状态栏或工具提示中的说明。请注意,标准属性框架目前不使用该字符串,因此可以将它保留为默认内容。此时将不生成“ 帮助文件 ” ,因此请删除该文本框中的项。6.单击“ 完成 ” ,将创建属性页对象。创建了以下三个文件:文件说明PolyProp.h 包含实现属性页的C+ 类CPolyProp。PolyProp.cpp 包含 PolyProp.h 文件。PolyProp.rgs 注册属性页对象的注册表脚本。还进行了以下代码更改:新属性页被添加到Polygon.cpp 中的对象项映射。PolyProp类被添加到Polygon.idl 文件。新注册表脚本文件PolyProp.rgs 被添加到项目资源。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 21 页 - - - - - - - - - 对话框模板被添加到属性页的项目资源。您指定的属性字符串被添加到资源字符串表。现在添加您希望出现在属性页上的字段。将字段添加到属性页1.在“ 解决方案资源管理器 ” 中,双击Polygon.rc 资源文件。这将打开“ 资源视图 ” 。2.在“ 资源视图 ” 中,展开“ Dialog”节点并双击 “ IDD_POLYPROP ”。 请注意,出现的对话框是空的,只有一个标签告诉您在此处插入控件。3.选择该标签, 并将其显示文本改为Sides:,方法是改变 “ 属性” 窗口中的 “ Caption”文本并调整标签框的大小:4.将工具箱中的一个编辑控件拖动到标签的右侧:5.最后,使用 “ 属性 ” 窗口将该编辑控件的“ ID ”更改为IDC_SIDES。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 21 页 - - - - - - - - - 这就完成了创建属性页资源的过程。添加用来创建和管理属性页的代码既然已经创建了属性页资源,现在需要编写实现代码了。首先,启用CPolyProp类以设置在按 “ 应用” 按钮时对象中的边数。修改 Apply 函数以设置边数像下面这样在PolyProp.h 中更改Apply函数:复制STDMETHOD(Apply)(void) USES_CONVERSION; ATLTRACE(_T(CPolyProp:Applyn); for (UINT i = 0; i m_nObjects; i+) CComQIPtr pPoly(m_ppUnki); short nSides = (short)GetDlgItemInt(IDC_SIDES); if FAILED(pPoly-put_Sides(nSides) CComPtr pError; CComBSTR strError; GetErrorInfo(0, &pError); pError-GetDescription(&strError); MessageBox(OLE2T(strError), _T(Error), MB_ICONEXCLAMATION); return E_FAIL; m_bDirty = FALSE; return S_OK; 一次可以有不止一个客户端附加到属性页,因此Apply函数不断循环, 并在每个客户端用从编辑框检索的值调用put_Sides。您使用的是CComQIPtr 类,此类对每个对象执行QueryInterface,以从 IUnknown接口(存储在m_ppUnk数组中)获取IPolyCtl接口。代码现在检查对Sides属性的设置是否真正有效。如果失败了, 则代码显示一个消息框,其中显示了 IErrorInfo接口中的错误详细信息。一般情况下,容器向对象请求ISupportErrorInfo接口并首先调用 InterfaceSupportsErrorInfo,以确定对象是否支持设置错误信息。您可以跳过此任务。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 21 页 - - - - - - - - - CComPtr 会通过自动处理引用计数来帮助您,因此您不需要对接口调用Release。CComBSTR 用BSTR 处理帮助您,因此您不必执行最终SysFreeString调用。您还使用各种字符串转换类之一,因此如有必要可以转换BSTR (这就是为什么在函数的开始处添加USES_CONVERSION 宏的原因)。还需要设置属性页的更新标志以指示应启用“ 应用” 按钮。这在用户更改“ 边” 编辑框中的值时发生。处理“ 应用 ” 按钮1.在“ 类视图 ” 中,右击CPolyProp 并在快捷菜单上单击 “ 属性” 。2.在“ 属性 ” 窗口中,单击 “ 事件” 图标。3.展开事件列表中的 “ IDC_SIDES”节点。4.选择“ EN_CHANGE”,并从右边的下拉菜单中单击“ OnEnChangeSides”。OnEnChangeSides处理程序声明将添加到Polyprop.h 中,处理程序实现将添加到Polyprop.cpp 中。接下来将修改处理程序。修改 OnEnChangeSides 方法将以下代码添加到Polyprop.cpp 中的OnEnChangeSides方法 (删除向导放在那里的任何代码) :复制LRESULT CPolyProp:OnEnChangeSides(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) SetDirty(TRUE); return 0; 当 WM_COMMAND消息与IDC_SIDES控件的 EN_CHANGE 通知一起发送时,将调用OnEnChangeSides。OnEnChangeSides然后调用SetDirty并传递TRUE以指示属性页现已更新,应启用 “ 应用 ” 按钮。向控件添加属性页由于您的项目中可能有多个控件,“ATL 添加类向导 ” 和“ATL 属性页向导 ” 不会自动将属性页添加到控件中。您需要将项添加到控件的属性映射。添加属性页打开 PolyCtl.h 并将下行添加到属性映射:复制名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 21 页 - - - - - - - - - PROP_ENTRY(Sides, 1, CLSID_PolyProp) 控件的属性映射现在看起来像这样:复制BEGIN_PROP_MAP(CPolyCtl) PROP_DATA_ENTRY(_cx, m_sizeExtent.cx, VT_UI4) PROP_DATA_ENTRY(_cy, m_sizeExtent.cy, VT_UI4) PROP_ENTRY(FillColor, DISPID_FILLCOLOR, CLSID_StockColorPage) PROP_ENTRY(Sides, 1, CLSID_PolyProp) / Example entries / PROP_ENTRY(Property Description, dispid, clsid) / PROP_PAGE(CLSID_StockColorPage) END_PROP_MAP() 您可能已经用属性页的CLSID 添加了PROP_PAGE宏,但如果按所显示的那样使用PROP_ENTRY宏,则在保存控件时也会保存Sides属性值。此宏的三个参数是属性说明、属性的 DISPID 和包含属性的属性页的CLSID。这很有用, 例如将控件加载到 Visual Basic 中并在设计时设置Sides 的数目时。由于保存了Sides 的数目,在重新加载Visual Basic 项目时, Sides 数目将还原。生成和测试控件现在生成那个控件并将其插入到“ActiveX 控件测试容器 ” 中。在 “ 测试容器 ” 中,在 “ 编辑” 菜单上单击“ PolyCtl 类对象 ” 。出现属性页;单击 “ 多边形 ” 选项卡。“ 应用” 按钮最初是禁用的。开始在“ 边” 框中键入值, “ 应用” 按钮将变成已启用的。输入完值之后,单击“ 应用 ” 按钮。控件显示更改,“ 应用” 按钮再次被禁用。尝试输入无效的值。您将看到一个消息框,其中包含您从put_Sides函数设置的错误说明。下一步,您将把控件放在Web 页上。步骤 7:将控件放在Web 页上Visual Studio .NET 2003控件现已完成。若要查看控件在现实情况中的工作,请将其放在Web 页上。定义控件时创建了一个包含控件的HTML 文件。从“ 解决方案资源管理器 ” 中打开PolyCtl.htm 文件,可以看到控件在Web 页上。在这一步中,您将撰写Web 页的脚本以响应事件。还将修改控件,让Internet Explorer 知道控件对于脚本撰写是安全的。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 19 页,共 21 页 - - - - - - - - - 撰写 Web 页的脚本控件仍然什么也不做,因此请更改Web 页以响应您发送的事件。撰写 Web 页的脚本打开 PolyCtl.htm 并选择 “HTML ” 视图。将下面以 粗体 显示的行添加到构成页的HTML 代码中。复制 ATL 3.0 test page for object PolyCtl OBJECT ID=PolyCtl 您已经添加了一些VBScript 代码,该代码从控件获取Sides 属性,并且当您在控件内部单击时,该代码会将边数增加一。如果在控件外部单击,则边数减少一。指出控件对于脚本撰写是安全的可以在 Internet Explore 中查看包含控件的Web 页,或者更方便一些, 使用 Visual C+ .NET 中内置的 Web 浏览器视图。若要在Web 浏览器视图中查看控件,请右击PolyCtl.htm ,然后单击 “ 在浏览器中查看 ” 。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 20 页,共 21 页 - - - - - - - - - 根据当前的Internet Explorer 安全设置, 您可能会收到一个 “ 安全警报 ” 对话框,指出该控件可能对于撰写脚本不安全, 并且可能造成损坏。 例如,如果您的控件既显示文件又有一个删除文件的Delete方法,那么仅在页上查看该控件是安全的。但撰写脚本则不安全,因为有人会调用Delete方法。安全说明为了学习本教程,您可以更改Internet Explorer 中的安全设置,以运行未标记为安全的ActiveX 控件。在控制面板中,单击“ Internet 属性” 并单击 “ 安全 ” 以更改相应的设置。当完成本教程后,请将安全设置更改回它们原来的状态。您可以通过编程提示Internet Explorer 不需要为此特定控件显示“ 安全警报 ” 对话框。这可以用IObjectSafety接口来实现, ATL 在类 IObjectSafetyImpl 中提供了此接口的实现。若要将此接口添加到控件,请将IObjectSafetyImpl添加到继承类列表,并在COM 映射中为其添加一项。将 IObjectSafetyImpl 添加到控件1.将以下行添加到PolyCtl.h 中继承类列表的末尾,并在上一行中添加一个逗号:复制public IObjectSafetyImpl 2.将下行添加到PolyCtl.h 中的 COM 映射:复制COM_INTERFACE_ENTRY(IObjectSafety) 生成和测试控件生成控件。生成完成后, 再次在浏览器视图中打开PolyCtl.htm 。 这次 Web 页应该直接显示, 没有 “ 安全警报 ” 对话框。在多边形内部单击;边数增加一。在多边形外部单击以减少边数。如果试图将边数减少到 3 以下,您将看到您设置的错误信息。下面是经过一次单击后的控件:名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 21 页,共 21 页 - - - - - - - - -