完整的 ActiveX Web 控件教程






4.92/5 (118投票s)
2006 年 6 月 21 日
17分钟阅读

2026243

20786
本文旨在帮助您快速掌握 ActiveX 控件的开发。它将向您展示开发 ActiveX 控件所需了解的基本概念,例如方法、属性和事件,以及如何实现 ActiveX 控件与网页之间的通信。
引言
ActiveX 是微软在上世纪 90 年代中期开发的一项技术,它允许创建类似小程序(applet)的应用程序,这些应用程序可以下载并在微软的 Web 浏览器中运行。本文面向的是那些希望学习如何开发第一个用于 Web 应用程序的 ActiveX 控件,但发现这很困难的 Visual C++ 开发人员。在我学习这项技术时,发现网上关于 ActiveX 的信息要么不再可用,要么过时,要么缺少关键信息,这使得我极难创建我的开发项目所需的 ActiveX 控件。本文旨在帮助您快速掌握 ActiveX 控件的开发。它将向您展示开发 ActiveX 控件所需了解的基本概念,例如方法、属性和事件,以及如何实现 ActiveX 控件与网页之间的通信。您将学会如何在 Windows XP 上使用 Internet Explorer 的默认安全设置来实现该控件,而不会收到未签名或不安全控件的警告消息。
在本教程中,我们将创建一个 ActiveX 控件,该控件在控件加载时显示一个进度条动画 GIF,以向用户指示控件正在加载和处理信息。该控件将包含演示如何与网页之间传递信息的函数。我们将一步一步指导您使用 Microsoft Visual Studio 2005 来创建该控件。
创建 ActiveX 控件
要创建 ActiveX 控件,请使用 Microsoft Visual Studio 2005 执行以下步骤
- 从“文件”菜单中,选择“新建”,然后选择“项目”。
- 在“新建项目”对话框中(如图 1 所示),在“项目类型”下,选择“Visual C++”,然后选择“MFC”。在“模板”下,选择“MFC ActiveX 控件”。
- 将项目命名为“MyActiveX”;在“位置”处,输入项目源代码的工作文件夹,然后单击“确定”按钮。
图 1. 新建项目对话框
- 在 MFC ActiveX 控件向导对话框中(如图 2 所示),选择“控件设置”。
- 在“创建控件的基础”下,选择“STATIC”。我们使用静态控件,因为我们只显示控件的输出而不接受输入。
- 在“附加功能”下,确保选中“可见时激活”和“无闪烁激活”,并且**不**选中“显示关于框对话框”。
图 2. MFC ActiveX 控件向导对话框
- 单击“完成”按钮,使 MFC ActiveX 控件向导能够创建项目的源代码。默认情况下,向导创建的项目使用共享 DLL 中的 MFC。我们需要更改此设置,因为除非在下载和运行该控件的系统上已安装所需的 MFC DLL,否则 ActiveX 控件将无法运行。这是导致 Web 页面上本应显示 ActiveX 控件的位置出现红色 X 的原因之一。从 Visual Studio 菜单中,选择“项目”,然后选择“属性”。导航到“配置属性”,然后选择“常规”。将“MFC 的使用”条目更改为“在静态库中使用 MFC”。
- 向导已创建以下三个类
CMyActiveXApp
– 这是从COleControlModule
派生的 ActiveX 应用程序类。它是派生 OLE 控件模块对象的基类,该对象包含用于初始化(InitInstance
)和代码清理(ExitInstance
)的成员函数。CMyActiveXCtrl
– 该类从基类COleControl
派生。这是我们将实现控件大部分功能的地方。CMyActiveXPropPage
– 该类从基类COlePropertyPage
派生。它用于管理控件的属性页对话框。ActiveX 控件向导已创建一个默认对话框用作控件的属性页。
添加对动画 GIF 的支持
为了实现从 ActiveX 控件显示进度条动画 GIF 的功能,我们将使用 Oleg Bykov 在 CodeProject 文章中提供的 CPictureEx
类。有关更多详细信息,请参阅“参考文献”部分。首先,通过在 VS 2005 中选择“解决方案资源管理器”选项卡,然后右键单击源树中的“头文件”或“源文件”,再选择“添加”、“现有项”来将源文件 pictureex.cpp 和 pictureex.h 添加到您的项目中。
要将动画 GIF 资源添加到项目中,我们必须绕过 Visual Studio 2005(以及 VS 2003)中的一个缺陷,该缺陷不允许导入 GIF 图像文件。如果您尝试这样做,将收到一个报告文件不是有效 GIF 文件的错误。您可以按以下方法解决此缺陷
- 将 GIF 文件 ProcessingProgressBar.gif 复制到您的项目工作文件夹,并将其重命名为 ProcessingProgressBar.gaf,文件扩展名为“gaf”。在“资源视图”中,右键单击资源文件 MyActiveX.rc,然后选择“添加资源”。在“添加资源”对话框中,按“导入”按钮,然后选择文件 ProcessingProgressBar.gaf。在“自定义资源类型”对话框中,为“资源类型”输入“GIF”,然后按 OK。这将把 GIF 图像文件导入到项目中。您将在“资源”下的“GIF”中找到它。导航到此项,并将控件 ID 从默认的
IDR_GIF1
更改为IDR_PROGRESSBAR
。 - 现在,我们需要纠正图像文件。首先,保存资源文件 MyActiveX.rc。导航到项目工作文件夹,并使用记事本编辑同一个资源文件。导航到
IDR_PROGRESSBAR
的行项目定义,并将引号中的文件名更改为“ProcessingProgressBar.gif”。同时,将工作文件夹中的 GIF 图像文件名更改为“ProcessingProgressBar.gif”。在记事本中,保存资源文件 MyActiveX.rc。Visual Studio 将报告文件 myactivex.rc 已在 Visual Studio 外部修改,请单击“是”重新加载文件。还需要进行一项更正。选择“解决方案资源管理器”,导航到项“ProcessingProgressBar.gaf”,然后选中它。在“属性”中,选择“相对路径”,并将文件名更正为“ProcessingProgressBar.gif”。
为进度条图形添加对话框
现在,我们将为进度条图形添加一个对话框。
- 在“资源视图”中,右键单击树中的对话框项,然后选择“插入对话框”以创建默认对话框。
- 删除不需要的 OK 和 Cancel 按钮,并将对话框大小调整为 230 x 40。
- 更改对话框的一些默认属性:边框 – 无,样式 – 子窗口,系统菜单 – 否,可见 – 是。
- 将控件 ID 更改为
IDD_MAINDIALOG
。 - 将一个图片控件插入到对话框中,方法是选择 Visual Studio 右侧的“工具箱”选项卡,选择一个图片控件,然后在对话框中单击。将控件大小调整为 200 x 20。将控件 ID 更改为
IDC_PROGRESSBAR
,并将颜色属性设置为白色。 - 为对话框创建一个类,方法是右键单击对话框并选择“添加类”。这将显示 MFC 类向导对话框(如图 3 所示)。将类命名为
CMainDialog
,基类为CDialog
。单击“完成”按钮,向导将为该类创建默认的源文件。
图 3. MFC 类向导 – CMainDialog
现在,我们为类添加成员变量。成员变量 m_MainDialog
与 CMainDialog
类相关联,而 m_ProgressBar
与我们在主对话框中添加的进度条控件相关联。
- 将成员变量
m_MainDialog
添加到CMyActiveXCtrl
类。选择“类视图”,右键单击CMyActiveXCtrl
,然后选择“添加”、“添加变量”。将“变量类型”输入为CMainDialog
,将“变量名”输入为m_MainDialog
,然后按“完成”按钮。 - 与上面类似,将成员变量
m_ProgressBar
添加到CMainDialog
类。将“变量类型”输入为CPictureEx
,将“变量名”输入为m_ProgressBar
,然后启用“控件变量”复选框,并确保为“控件 ID”输入了IDC_PROGRESSBAR
。在单击“完成”按钮之前,请确保“变量类型”设置为CPictureEx
而不是更改为CStatic
。
图 4. 添加成员变量向导 – m_ProgressBar
添加支持代码
现在,我们来添加一些代码来支持绘制主对话框和进度条控件。
- 选择
CMyActiveXCtrl
类。在“属性”表中,选择“消息”图标,然后选择WM_CREATE
。选择WM_CREATE
右侧的列表框,然后选择“<添加> OnCreate”为WM_CREATE
消息添加一个方法。向导会将OnCreate
方法添加到CMyActiveXCtrl
类。 - 编辑 MyActiveXCtrl.cpp,并将以下代码添加到
OnCreate
方法以创建主对话框m_MainDialog.Create(IDD_MAINDIALOG, this);
将以下代码添加到
OnDraw
方法以调整主对话框窗口的大小并填充背景m_MainDialog.MoveWindow(rcBounds, TRUE); CBrush brBackGnd(TranslateColor(AmbientBackColor())); pdc->FillRect(rcBounds, &brBackGnd);
- 选择
CMainDialog
类。在“属性”表中,选择“消息”图标,然后选择WM_CREATE
。选择WM_CREATE
右侧的列表框,然后选择“<添加> OnCreate”为WM_CREATE
消息添加一个方法。向导会将OnCreate
方法添加到CMainDialog
类。 - 编辑 MainDialog.cpp,并将以下代码添加到
OnCreate
方法以加载和绘制进度条动画 GIF 图像if (m_ProgressBar.Load(MAKEINTRESOURCE(IDR_PROGRESSBAR),_T("GIF"))) m_ProgressBar.Draw();
确保生成配置设置为“发布”配置,然后生成 MyActiveX ActiveX 应用程序。
创建 ActiveX 控件的网页
用于快速创建默认网页以测试您的控件的首选工具是 Microsoft 的 ActiveX 控件安装程序。您可以从微软下载。
您也可以在互联网上的其他各种站点找到它。将其安装在您使用 Microsoft Visual Studio 开发控件的同一系统上。为了方便应用程序的初始测试,您应该确保 Microsoft IIS Web 服务器也安装在此同一系统上。
首次运行 ActiveX 控件安装程序时,它会为您创建一个默认的 HTML 网页。要插入 ActiveX 控件,请右键单击 HTML 源的 <BODY>
标记内的任意位置,然后选择“插入 ActiveX 控件”。在“插入 ActiveX 控件”对话框中,向下滚动并选择您使用 Visual Studio 创建的“MyActiveX 控件”,然后单击 OK。
图 5. ActiveX 控件安装程序 – 插入 ActiveX 控件
ActiveX 控件安装程序将显示两个对话框,使您能够修改控件。“属性”对话框用于修改控件的属性,“编辑 ActiveX 控件”对话框用于手动编辑控件。您可以关闭这两个对话框,因为我们可以通过手动编辑 HTML 代码进行任何进一步的更改。您现在应该会在 HTML 代码中找到一个 OBJECT ID
标记,类似于图 6 所示。通过在 OBJECT ID
标记中将 “WIDTH=350”
和 “HEIGHT=50”
更改控件的大小参数。将网页的 HTML 文件保存为 IIS Web 服务器的根文件夹 wwwroot 中的文件 myactivex.htm。
图 6. ActiveX 控件安装程序 – MyActiveX ActiveX 控件
要测试 ActiveX 控件,请使用 Internet Explorer 加载网页 https:///myactivex.htm。如果您收到任何警告消息,只需单击 OK 继续。这应该会在网页中显示一个进度条动画 GIF。如果未显示,或者在本应显示 ActiveX 控件的位置看到红色 X,则很可能是由于浏览器安全设置阻止了 ActiveX 控件的加载和运行。要纠正此问题,请修改 Internet Explorer 中的安全设置,将与 ActiveX 相关的所有设置更改为“启用”。
图 7. Internet Explorer 中的 MyActiveX 控件
接下来,我们需要构建 ActiveX 控件,以便从 Internet Explorer 浏览器加载它时不会出现有关未签名或不安全控件的烦人错误消息。
构建已签名的 ActiveX 控件
要创建已签名的 ActiveX 控件,您必须从证书提供商(如 Thawte、Verisign 或 GeoTrust)之一购买代码签名证书。通过此服务,他们将验证您的身份并提供用于签名 ActiveX 应用程序的证书文件。我选择了 Thawte 的代码签名证书,他们为签名应用程序提供了两个文件:mycert.spc 和 mykey.pvk。
要签名 ActiveX 应用程序,我们将应用程序的组件打包到一个 CAB 文件中,该文件将从网站下载,然后 ActiveX 控件将被安装在系统上。安装 ActiveX 控件的一部分包括注册该控件。为了实现这一点,必须使用 ActiveX 控件的 VERSIONINFO
结构中定义的 OLESelfRegister
值来构建该控件。Microsoft Visual Studio 的版本(最高到 VS 2003)会插入此条目,但 Visual Studio 2005 不会。要添加该条目,请编辑资源文件 myactivex.rc 以添加 OLESelfRegister
值,如下所示
VS_VERSION_INFO VERSIONINFO FILEVERSION 1,0,0,1 PRODUCTVERSION 1,0,0,1 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x4L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "TODO: <Company name>" VALUE "FileDescription", "TODO: <File description>" VALUE "FileVersion", "1.0.0.1" VALUE "InternalName", "MyActiveX.ocx" VALUE "LegalCopyright", "TODO: (c) <Company name>. All rights reserved." VALUE "OLESelfRegister", "\0" VALUE "OriginalFilename", "MyActiveX.ocx" VALUE "ProductName", "TODO: <Product name>" VALUE "ProductVersion", "1.0.0.1" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1252 END END
在签名应用程序之前,应将 ActiveX 控件打包到 CAB 文件中。此 CAB 文件还将包含一个用于安装您的 ActiveX 控件的 INF 文件。要构建 CAB 文件,您需要 Microsoft Cabinet 软件开发工具包中提供的 cabarc.exe 工具。下面是一个简单的 INF 文件的示例,可用于将 MyActiveX 控件打包到 CAB 文件中。对于 CLSID 行项目,您应将值更改为与您之前使用 ActiveX 控件安装程序创建的 HTML 网页中的 OBJECT ID
标记中的值相同。
[Add.Code]
myactivex.ocx=myactivex.ocx
myactivex.inf=myactivex.inf
[myactivex.ocx]
file=thiscab
clsid={36299202-09EF-4ABF-ADB9-47C599DBE778}
RegisterServer=yes
FileVersion=1,0,0,0
[myactivex.inf]
file=thiscab
要创建 CAB 文件,请按如下所示运行 cabarc。**重要提示**:确保 OCX 和 INF 文件与您运行 cabarc.exe 的目录相同,否则从 Web 服务器下载后 CAB 文件将无法正确提取。这是导致 Web 页面上本应显示 ActiveX 控件的位置出现红色 X 的问题之一。
cabarc -s 6144 N myactivex.cab myactivex.ocx myactivex.inf
要签名您创建的 CAB 文件,您需要 Microsoft MSDN 中的 signcode.exe 工具。有关详细信息,请参阅本文结尾处的“使用 Authenticode 进行签名和检查”参考。您可以使用 signcode 工具和从购买代码签名证书获得的证书文件来签名 CAB 文件。下面是一个使用 signcode 签名 myactivex.cab 的示例
signcode -n "myactivex" -i
http://www.myactivex.com -spc mycert.spc -v mykey.pvk -t
http://timestamp.verisign.com/scripts/timstamp.dll myactivex.cab
在上面的示例中,http://www.myactivex.com 应替换为您提供有关您的已签名 ActiveX 控件的更多信息的网页。
要在 Web 页面中使用已签名的 CAB 文件,首先将 myactivex.cab 复制到您的网站上的一个文件夹中,然后必须使用 CODEBASE
参数修改 Web 页面上的 OBJECT ID
标记,以引用此 CAB 文件。有关示例,请参阅图 8。如果在 Internet Explorer 中加载此页面,它应下载 CAB 文件并安装您的 ActiveX 控件,而不会出现有关未签名 ActiveX 控件的警告。
图 8. ActiveX 控件安装程序 – 带有 CODEBASE 的 MyActiveX
构建安全的 ActiveX 控件
要创建一个在 Internet Explorer 中加载时不会出现不安全控件警告或错误消息的控件,您必须实现代码以确保 ActiveX 控件的安全初始化和安全脚本。有关如何执行此操作的详细信息,请参阅 Microsoft MSDN 上的“ActiveX 控件的安全初始化和脚本”一文。有关详细信息,请参阅本文结尾处的“参考文献”。我发现这篇文章中存在遗漏和错误,已在本文中进行了更正。基本上,需要做的就是向 DllRegisterServer
和 DllUnregisterServer
方法添加代码。以下是使您的 ActiveX 控件安全的步骤指南
- 编辑 MyActiveX.cpp 并添加以下代码。
CLSID_SafeItem
的值应从 MyActiveXCtrl.cpp 源文件中的IMPLEMENT_OLECREATE_EX
或您 ActiveX 控件的等效项中获取。它也将与 HTML 页面上包含您的 ActiveX 控件的OBJECT ID
标记中的 **CLSID** 值相同。#include "comcat.h" #include "strsafe.h" #include "objsafe.h" // CLSID_SafeItem - Necessary for safe ActiveX control // Id taken from IMPLEMENT_OLECREATE_EX function in xxxCtrl.cpp const CATID CLSID_SafeItem = { 0x36299202, 0x9ef, 0x4abf,{ 0xad, 0xb9, 0x47, 0xc5, 0x99, 0xdb, 0xe7, 0x78}}; // HRESULT CreateComponentCategory - Used to register ActiveX control as safe HRESULT CreateComponentCategory(CATID catid, WCHAR *catDescription) { ICatRegister *pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (FAILED(hr)) return hr; // Make sure the HKCR\Component Categories\{..catid...} // key is registered. CATEGORYINFO catinfo; catinfo.catid = catid; catinfo.lcid = 0x0409 ; // english size_t len; // Make sure the provided description is not too long. // Only copy the first 127 characters if it is. // The second parameter of StringCchLength is the maximum // number of characters that may be read into catDescription. // There must be room for a NULL-terminator. The third parameter // contains the number of characters excluding the NULL-terminator. hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len); if (SUCCEEDED(hr)) { if (len>127) { len = 127; } } else { // TODO: Write an error handler; } // The second parameter of StringCchCopy is 128 because you need // room for a NULL-terminator. hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription); // Make sure the description is null terminated. catinfo.szDescription[len + 1] = '\0'; hr = pcr->RegisterCategories(1, &catinfo); pcr->Release(); return hr; } // HRESULT RegisterCLSIDInCategory - // Register your component categories information HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid) { // Register your component categories information. ICatRegister *pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) { // Register this category as being "implemented" by the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; } // HRESULT UnRegisterCLSIDInCategory - Remove entries from the registry HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid) { ICatRegister *pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) { // Unregister this category as being "implemented" by the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; }
- 修改
DllRegisterServer
方法以添加突出显示的代码,如下所示STDAPI DllRegisterServer(void) { HRESULT hr; // HResult used by Safety Functions AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS); // Mark the control as safe for initializing. hr = CreateComponentCategory(CATID_SafeForInitializing, L"Controls safely initializable from persistent data!"); if (FAILED(hr)) return hr; hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED(hr)) return hr; // Mark the control as safe for scripting. hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!"); if (FAILED(hr)) return hr; hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); if (FAILED(hr)) return hr; return NOERROR; }
- 修改
DllUnregisterServer
方法以添加突出显示的代码,如下所示STDAPI DllUnregisterServer(void) { HRESULT hr; // HResult used by Safety Functions AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) return ResultFromScode(SELFREG_E_CLASS); // Remove entries from the registry. hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); if (FAILED(hr)) return hr; hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); if (FAILED(hr)) return hr; return NOERROR; }
ActiveX 控件的属性、方法和事件
ActiveX 控件与网页之间的通信是通过 ActiveX 控件的属性、方法和事件进行的。为了演示这些概念,我们将创建一个简单的网页,其中包含一个用于输入文本字符串的表单。当按下“提交”按钮时,通过输入参数自定义属性将输入的文本传递到 ActiveX 控件。将调用控件的一个方法,该方法将此文本复制到输出参数自定义属性,然后触发一个事件,以便在网页上显示此文本。只需在 Visual Studio 中按照以下步骤实现即可
- 首先,我们将创建自定义属性,用于将文本传递到 ActiveX 控件和从 ActiveX 控件传递出来。在“类视图”中,展开“MyActiveXLib”元素以选择“_DMyActiveX”。右键单击“_DMyActiveX”,然后选择“添加”、“添加属性”。在“添加属性”向导对话框(如图 9 所示)中,选择
BSTR
作为“属性类型”,并输入“InputParameter
”作为“属性名”。向导将自动为您填充其他字段:“m_InputParameter”作为“变量名”,以及“OnInputParameterChanged”作为“通知函数”。单击“完成”按钮,向导将自动创建支持此属性的代码。对属性名“OutputParameter
”和相同的属性类型BSTR
执行相同的操作。图 9. 添加属性向导
- 接下来,我们将创建一个方法,使网页能够通知控件将输入的文本参数传输到输出参数。在“类视图”中,展开“MyActiveXLib”元素以选择“_DMyActiveX”。右键单击“_DMyActiveX”,然后选择“添加”、“添加方法”。在“添加属性”向导对话框(如图 9 所示)中,选择
void
作为返回类型,并输入“LoadParameter
”作为方法名。向导将自动输入“LoadParameter
”作为内部名。单击“完成”,向导将自动创建支持此方法。的代码。图 10. 添加方法向导
- 现在,我们将创建一个事件,使 ActiveX 控件能够通知网页它已完成将文本从输入参数传输到输出参数。网页中的代码将响应此事件,并通过显示输出参数中的文本来验证此传输已由 ActiveX 控件完成。在“类视图”中,右键单击
CMyActiveXCtrl
,选择“添加”、“添加事件”。在“添加事件”向导(如图 11 所示)中,输入“ParameterLoaded
”作为“事件名”,并将“内部名”更改为“FireParameterLoaded
”。单击“完成”,向导将创建默认代码来支持此事件。图 11. 添加事件向导
有了以上这些,向导已经为您创建了大部分代码。我们只需要添加两行代码来实现 ActiveX 控件复制文本并通过事件通知网页代码的功能。编辑源文件 MyActiveXCtrl.cpp,并将以下代码添加到 LoadParameter
方法。
// Copy text from the input parameter to the output parameter m_OutputParameter = m_InputParameter; // Fire an event to notify web page FireParameterLoaded();
要进行测试,请使用 ActiveX 控件安装程序创建以下 HTML 代码
<HTML>
<HEAD>
<TITLE>MyActiveX - Methods, Properties, and Events</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function PassParameter()
{
if (StringInput.value != " ")
{
MyActiveX1.InputParameter = StringInput.value;
MyActiveX1.LoadParameter();
}
}
</SCRIPT>
</HEAD>
<BODY>
<center>
MyActiveX - Methods, Properties, and Events Example
<p></p>
<OBJECT ID="MyActiveX1" WIDTH=350 HEIGHT=50
CLASSID="CLSID:36299202-09EF-4ABF-ADB9-47C599DBE778">
<PARAM NAME="_Version" VALUE="65536">
<PARAM NAME="_ExtentX" VALUE="2646">
<PARAM NAME="_ExtentY" VALUE="1323">
<PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
<p></p>
Input Parameter: <INPUT TYPE ="text" NAME="StringInput" VALUE=" ">
<p></p>
<INPUT TYPE="button" NAME="Submit"
VALUE="Submit" ONCLICK=PassParameter()>
<SCRIPT FOR=MyActiveX1 EVENT=ParameterLoaded()>
<!-- {
window.document.write("The parameter you entered is:<br> "
+ MyActiveX1.OutputParameter + " ")
-->
</SCRIPT>
</center>
</BODY>
将此 HTML 代码保存到您的 Web 服务器并运行它。您应该会看到一个网页,其中显示一个进度条和一个用于输入“Input Parameter”文本的表单。在字段中输入文本,然后按“提交”。这应该会显示一个新页面,其中包含“您输入的参数是:”,后面跟着您输入的文本。以下是对 HTML 代码的简要说明。
当您按下“提交”按钮时,将调用 JavaScript 函数 PassParameter
。此函数将文本从 StringInput
表单字段复制到 ActiveX 控件的 InputParameter
属性。然后,它会调用控件的 LoadParameter
方法,该方法将文本从 InputParameter
复制到 OutputParameter
,并调用 FireParameterLoaded()
以触发 ActiveX 事件。然后,以下 HTML 代码将响应此事件
<SCRIPT FOR=MyActiveX1 EVENT=ParameterLoaded()>
<!-- {
window.document.write("The parameter you entered is:<br> " +
MyActiveX1.OutputParameter + " ")
-->
</SCRIPT>