标记ocx控件为脚本安全
MFC开发的OCX控件即使使用了签名。在IE中运行是也会提示“页面中的OCX的交互是不安全的。。。。”。解决办法有两种
方案1:修改IE的设置:
方案2:标记控件为脚本安全的
在工程中增加头文件 cathelp.h
#ifndef _CATHELP_H_#define _CATHELP_H_#include <comcat.h>HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription);HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid);#endif
增加cathelp.cpp
#include "cathelp.h"
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';if(pcr)
{hr = pcr->RegisterCategories(1, &catinfo);pcr->Release();}return hr;
}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(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;
}
修改 ocx的 DllRegisterServer 方法
#include "cathelp.h"
#include <objsafe.h>//for CATID_SafeForInitializing
#include "SafeocxtestCtl.h"
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(
CSafeocxtestCtrl::guid, CATID_SafeForScripting) ))return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( RegisterCLSIDInCategory(
CSafeocxtestCtrl::guid, CATID_SafeForInitializing) ))return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{AFX_MANAGE_STATE(_afxModuleAddrThis);if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
// 控件安全反初始化
UnRegisterCLSIDInCategory( CSafeocxtestCtrl::guid, CATID_SafeForScripting);UnRegisterCLSIDInCategory( CSafeocxtestCtrl::guid, CATID_SafeForInitializing);return NOERROR;
}
编译注册就OK了。
如果要查看ocx是否是脚本安全的。在注册表HKEY_CLASSES_ROOT\CLSID\OCX的clsid\Implemented Categories\ 下看一下有没有“{7DD95801-9882-11CF-9FA9-00AA006C42C4}” 和“{7DD95802-9882-11CF-9FA9-00AA006C42C4}”
下图就是脚本安全的:
参考:http://support.microsoft.com/kb/161873/en-us