ActiveX 控件是 OLE 控件规范的更新版本。
重要
ActiveX 是一项不推荐用于新开发的旧技术。 有关详细信息,请参阅 ActiveX 控件。
控件是开发可编程软件组件的主要体系结构,可用于各种不同容器,包括 Internet 上的 COM 感知 Web 浏览器。 任何 ActiveX 控件都可以是 Internet 控件,并且可以将其功能添加到活动文档或成为网页的一部分。 网页上的控件可以使用脚本相互通信。
ActiveX 控件不限于 Internet。 只要控件支持该容器所需的接口,ActiveX 控件也可用于任何容器。
ActiveX 控件具有多项优势,包括:
所需的接口比以前的 OLE 控件少。
能够无窗口且始终处于就地活动状态。
若要成为 ActiveX 控件,控件必须:
IUnknown
支持接口。是 COM 对象。
导出 DLLRegisterServer 和 DLLUnRegisterServer。
支持功能所需的其他接口。
使现有控件 Internet-Friendly
设计在 Internet 环境中运行良好的控件需要考虑 Internet 上的传输速率相对较低。 可以使用现有控件;但是,应该执行一些步骤来减小代码大小,并异步下载控件属性。
若要提高控件的性能,请遵循以下有关效率注意事项的提示:
实现 ActiveX 控件:优化一文中所述的技术。
请考虑如何实例化控件。
异步;不要按住其他程序。
在小块中下载数据。
下载大型流(如位图或视频数据)时,请与容器协作以异步方式访问控件的数据。 以增量或渐进方式检索数据,与其他可能同时检索数据的其他控件合作。 代码也可以异步下载。
在后台下载代码和属性。
尽快激活用户界面。
考虑如何存储持久性数据,包括属性和大型数据 BLOB(例如位图图像或视频数据)。
具有大量持久数据的控件(如大型位图或 AVI 文件)需要注意下载方法。 文档或页面可以尽快可见,并允许用户在控件检索后台数据时与页面交互。
编写高效的例程以保持代码大小和运行时间。
小型按钮和标签控件(仅包含少量字节的持久性数据)适用于 Internet 环境,并且适用于浏览器内部。
考虑将进度传达给容器。
在异步下载中通知容器进度,包括用户何时可以开始与页面交互,以及下载完成后。 容器可以向用户显示进度(如完成百分比)。
考虑如何在客户端计算机上注册控件。
创建新的 ActiveX 控件
使用应用程序向导创建新控件时,可以选择启用对异步名字对象和其他优化的支持。 若要添加异步下载控件属性的支持,请执行以下步骤:
使用 MFC ActiveX 控件向导创建项目
单击“文件”菜单上的“新建”。
从 Visual Studio 中选择 MFC ActiveX 控件向导 C++项目并命名项目。
在 “控件设置” 页上,选择 “异步加载属性”。 选择此选项会为你设置就绪状态属性和就绪状态更改事件。
还可以选择其他优化,如 ActiveX 控件:优化中所述的无窗口激活。
选择“完成”以创建项目。
创建派生自 CDataPathProperty 的类
创建派生自
CDataPathProperty
. 的类。在包含控件头文件的每个源文件中,在此类的头文件之前添加此文件的头文件。
在此类中,重写
OnDataAvailable
。 每当数据可供显示时,将调用此函数。 当数据变得可用时,你可以以任何方式处理它,例如,通过逐步呈现它。下面的代码摘录是逐步在编辑控件中显示数据的简单示例。 请注意使用标志 BSCF_FIRSTDATANOTIFICATION 清除编辑控件。
void CMyDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag) { CListCtrl list_ctrl; CEdit *edit = list_ctrl.GetEditControl(); if ((bscfFlag & BSCF_FIRSTDATANOTIFICATION) && edit->m_hWnd) { edit->SetSel(0, -1); edit->Clear(); } if (dwSize > 0) { CString string; LPTSTR str = string.GetBuffer(dwSize); UINT nBytesRead = Read(str, dwSize); if (nBytesRead > 0) { string.ReleaseBuffer(nBytesRead); edit->SetSel(-1, -1); edit->ReplaceSel(string); } } }
请注意,必须包括 AFXCMN。要使用该类的
CListCtrl
H。当控件的总体状态发生更改(例如,从加载到初始化或用户交互),调用
COleControl::InternalSetReadyState
。 如果控件只有一个数据路径属性,则可以在 BSCF_LASTDATANOTIFICATION 上添加代码,以通知容器下载已完成。 例如:if (bscfFlag & BSCF_LASTDATANOTIFICATION) { GetControl()->InternalSetReadyState(READYSTATE_COMPLETE); }
替代
OnProgress
。 在中OnProgress
,你将传递一个数字,其中显示最大范围,一个数字显示当前下载的距离。 可以使用这些数字向用户显示状态,例如完成百分比。
下一过程将属性添加到控件,以使用刚刚派生的类。
添加属性
在 类视图中,右键单击库节点下方的接口,然后选择“ 添加”,然后选择“ 添加属性”。 这将启动 “添加属性向导”。
在 “添加属性向导”中,选择 “设置/获取方法 ”单选按钮,键入 属性名称,例如 EditControlText,然后选择 BSTR 作为 属性类型。
单击“完成”。
将 -derived 类的成员
CDataPathProperty
变量声明到 ActiveX 控件类。CMyDataPathProperty EditControlText;
Get/Set
实现方法。 对于Get
,返回字符串。 对于Set
,加载属性和调用SetModifiedFlag
。BSTR CMFCActiveXControlCtrl::GetEditControlText(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CString strResult; strResult = EditControlText.GetPath(); return strResult.AllocSysString(); } void CMFCActiveXControlCtrl::SetEditControlText(LPCTSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); Load(newVal, EditControlText); SetModifiedFlag(); }
在 DoPropExchange 中,添加以下行:
PX_DataPath(pPX, _T("DataPath"), EditControlText);
重写 ResetData 以通过添加以下行来通知属性重置其控件:
EditControlText.ResetData();
决定是否派生自 CDataPathProperty 还是 CCachedDataPathProperty
前面的示例介绍了从中派生控件属性 CDataPathProperty
的步骤。 如果要下载经常更改的实时数据,并且不需要保留所有数据,但仅保留当前值,则这是一个不错的选择。 例如股票时钟周期控件。
也可以派生自 CCachedDataPathProperty
。 在这种情况下,下载的数据缓存在内存文件中。 如果需要保留所有下载的数据(例如,以渐进方式呈现位图的控件),这是一个不错的选择。 在这种情况下,该类具有包含数据的成员变量:
CMemFile m_Cache;
在 ActiveX 控件类中,可以使用此内存映射文件 OnDraw
来显示数据。 在 ActiveX 控件 CCachedDataPathProperty
派生类中,在调用基类实现后重写成员函数 OnDataAvailable
并使控件失效。
void CMyCachedDataPathProperty::OnDataAvailable(DWORD dwSize, DWORD bscfFlag)
{
CCachedDataPathProperty::OnDataAvailable(dwSize, bscfFlag);
GetControl()->InvalidateControl();
}
使用 ActiveX 控件异步下载数据
应以异步方式通过网络下载数据。 这样做的优点是,如果传输大量数据或连接速度缓慢,则下载过程不会阻止客户端上的其他进程。
异步名字对象提供了一种通过网络异步下载数据的方法。 异步名字对象的读取作会立即返回,即使作尚未完成。
例如,如果只有 10 个字节可用,并且读取在 1K 文件上异步调用,则 Read 不会阻止,但返回当前可用的 10 个字节。
使用类实现异步名字对象CAsyncMonikerFile
。 但是,ActiveX 控件可以使用 CDataPathProperty
派生自 CAsyncMonikerFile
的类来帮助实现异步控件属性。
在网页上显示控件
下面是用于在网页上插入控件的对象标记和属性的示例。
<OBJECT
CLASSID="clsid:FC25B780-75BE-11CF-8B01-444553540000"
CODEBASE="/ie/download/activex/iechart.ocx"
ID=chart1
WIDTH=400
HEIGHT=200
ALIGN=center
HSPACE=0
VSPACE=0>
<PARAM NAME="BackColor" value="#ffffff"/>
<PARAM NAME="ForeColor" value="#0000ff"/>
<PARAM NAME="url" VALUE="/ie/controls/chart/mychart.txt"/>
</OBJECT>
更新现有 OLE 控件以使用新的 ActiveX 控件功能
如果 OLE 控件是使用 4.2 之前的 Visual C++ 版本创建的,则可以执行一些步骤来提高其性能并增强其功能。 有关这些更改的详细讨论,请参阅 ActiveX 控件:优化。
如果要向现有控件添加异步属性支持,则需要自行添加就绪状态属性和 ReadyStateChange
事件。 在控件的构造函数中,添加:
m_lReadyState = READYSTATE_LOADING;
通过调用 COleControl::InternalSetReadyState 下载代码时,将更新就绪状态。 你可以调用的一个位置是从 OnProgress
-derived 类的重写中调用InternalSetReadyState
的CDataPathProperty
。