创建安全的ActiveX控件
要想创建一个能够在IE中成功加载而没有“不安全”的警告或者错误提示信息的ActiveX控件,我们必须实现安全的初始化和脚本。关于安全初始化的更加详细的信息,请参考本文结尾的参考资料“Safe Initialization and Scripting for ActiveX Controls”。基本上,所有要做的工作都是在DllRegisterServer 和DllUnregisterServer这两个函数中完成的。下面,我们就来一步步地将我们的ActiveX控件变成一个“安全的”控件。
1.编辑MyActiveX.cpp并添加如下的代码。其中,CLSID_SafeItem的值应该跟MyActiveXCtrl.cpp中的IMPLEMENT_OLECREATE_EX一致,这就等同于你的ActiveX控件。同样,它也应该跟你的HTML页面中的OBJECT ID标签中的CLSID一致。
#include
"
comcat.h
"
#include
"
strsafe.h
"
#include
"
objsafe.h
"
//
CLSID_SafeItem – 安全的ActiveX控件所必须的内容
//
ID的值跟xxxCtrl.cpp文件中的IMPLEMENT_OLECREATE_EX一致
const
CATID CLSID_SafeItem
=
{
0x36299202
,
0x9ef
,
0x4abf
,{
0xad
,
0xb9
,
0x47
,
0xc5
,
0x99
,
0xdb
,
0xe7
,
0x78
}};
//
HRESULT CreateComponentCategory – 用于注册安全的ActiveX控件
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;
//
确认HKCR/Component Categories/{..catid...}键值被注册
CATEGORYINFO catinfo;
catinfo.catid
=
catid;
catinfo.lcid
=
0x0409
;
//
english
size_t len;
//
确认描述不是太长。
//
只复制开始的127个字符。
//
StringCchLength的第二个参数表示被读入catDescription的最大字符数。
//
第三个参数表示字符串的长度
hr
=
StringCchLength(catDescription, STRSAFE_MAX_CCH,
&
len);
if
(SUCCEEDED(hr))
{
if
(len
>
127
)
{
len
=
127
;
}
}
else
{
//
TODO: Write an error handler;
}
hr
=
StringCchCopy(catinfo.szDescription, len
+
1
, catDescription);
//
添加字符串结束符.
catinfo.szDescription[len
+
1
]
=
'
/0
'
;
hr
=
pcr
->
RegisterCategories(
1
,
&
catinfo);
pcr
->
Release();
return
hr;
}
//
HRESULT RegisterCLSIDInCategory -
//
注册组件分类信息
HRESULT RegisterCLSIDInCategory(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))
{
CATID rgcatid[
1
] ;
rgcatid[
0
]
=
catid;
hr
=
pcr
->
RegisterClassImplCategories(clsid,
1
, rgcatid);
}
if
(pcr
!=
NULL)
pcr
->
Release();
return
hr;
}
//
HRESULT UnRegisterCLSIDInCategory
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))
{
CATID rgcatid[
1
] ;
rgcatid[
0
]
=
catid;
hr
=
pcr
->
UnRegisterClassImplCategories(clsid,
1
, rgcatid);
}
if
(pcr
!=
NULL)
pcr
->
Release();
return
hr;
}
2.修改 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);
//
为初始化标记控件为安全控件
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;
//
为脚本标记控件为安全控件
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;
}
3.修改 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);
hr
=
UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);
if
(FAILED(hr))
return
hr;
hr
=
UnRegisterCLSIDInCategory(CLSID_SafeItem,
CATID_SafeForScripting);
if
(FAILED(hr))
return
hr;
return
NOERROR;
原文:http://blog.sina.com.cn/s/blog_561a69f10100gas6.html