有两个控件可用于消除这些错误的方法。第一个涉及实现 IObjectSafety 接口的控件,可用于来更改它们的行为变得"安全"如果在 Internet 浏览器的上下文中运行的控件。第二步是修改控件的 DllRegisterServer 函数,可在注册表中标记该控件的"安全"。这篇文章讲述这些方法中的第二个。第一种方法,实现 IObjectSafety 接口,Internet 客户端 SDK 中介绍。
请记住控件应仅标记为安全,如果是,事实上,安全。请参考此说明的 Internet 客户端 SDK 文档。请参阅"安全初始化和脚本的 ActiveX 控件"部分下面的组件开发。
注意:本文不介绍如何将控件标记为可安全执行下载。有关代码下载和代码签名的详细信息,请参阅 Internet 客户端 SDK。
请按照以下步骤将 MFC ActiveX 控件标记为已对脚本编写是安全的和对初始化是安全的:
向项目中添加下面的 cathelp.h 和 cathelp.cpp 文件来实现 CreateComponentCategory 和 RegisterCLSIDInCategory 的 helper 函数。
Cathelp.h
#include "comcat.h"
// Helper function to create a component category and associated
// description
HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);
// Helper function to register a CLSID as belonging to a component
// category
HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
Cathelp.cpp
#include "comcat.h"
// Helper function to create a component category and associated
// description
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
// Make sure the provided description is not too long.
// Only copy the first 127 characters if it is
int len = wcslen(catDescription);
if (len>127)
len = 127;
wcsncpy(catinfo.szDescription, catDescription, len);
// Make sure the description is null terminated
catinfo.szDescription[len] = '\0';
hr = pcr->RegisterCategories(1, &catinfo);
pcr->Release();
return hr;
}
// Helper function to register a CLSID as belonging to a component
// category
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;
}
修改 DllRegisterServer 标记为安全的控件。在.cpp 文件在项目中找到 DllRegisterServer 的实现。您将需要此.cpp 文件中添加几个方面。包括实现 CreateComponentCategory 和 RegisterCLSIDInCategory 文件:
#include "CatHelp.h"
定义与安全组件类别关联的 GUID:
const CATID CATID_SafeForScripting =
{0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
const CATID CATID_SafeForInitializing =
{0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4}};
定义与您的控件关联的 GUID。为简单起见,您可以贷款从控件的主.cpp 文件中的IMPLEMENT_OLECREATE_EX宏的 GUID。稍微调整格式,以使其类似于以下:
const GUID CDECL BASED_CODE _ctlid =
{ 0x43bd9e45, 0x328f, 0x11d0,
{ 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
若要将控件标记为安全的脚本和初始化,请按如下方式修改 DllRegisterServer 函数:
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( CreateComponentCategory(
CATID_SafeForScripting,
L"Controls that are safely scriptable") ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( CreateComponentCategory(
CATID_SafeForInitializing,
L"Controls safely initializable from persistent data") ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( RegisterCLSIDInCategory(
_ctlid, CATID_SafeForScripting) ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( RegisterCLSIDInCategory(
_ctlid, CATID_SafeForInitializing) ))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}
这些原因有两个不正常情况下应修改 DllUnregisterServer 函数:
您不想删除组件类别,因为其他控件可能正在使用它。
虽然没有定义一个 UnRegisterCLSIDInCategory 函数,但默认情况下 DllUnregisterServer 控件的项,从注册表删除完全。因此,从控件的注册删除类别是几乎没有什么用处。
在编译并注册您的控件,会在注册表中找到以下项:
HKEY_CLASSES_ROOT\Component
Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\Component
Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented
Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented
Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}