VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程
三、MFC Activex 安全问题:
1、在默认环境下,编译的MFC Activex控件,只能在本地代码中运行,即在http://localhost/xxx/xxx.htm中执行,而在http://127.0.0.1/xxx/xxx.htm中提示无相关属性,需要设置其初始化和脚本运行的安全性
ActiveX在远程IE页面上执行,需要实现安全接口。
在ATL写的ActiveX中,用IObjectSafety。
http://support.microsoft.com/kb/168371/en-us
在MFC写的ActiveX中,直接修改注册表。
http://support.microsoft.com/kb/161873/en-us
mfc实现的ocx,要在app实现文件中包括两个文件:
在ActivexDemo.cpp 文件中实现以下方法
#include " stdafx.h "
#include " ActivexDemo.h "
#include < comcat.h >
#include < objsafe.h >
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CActivexDemoApp theApp;
const GUID CDECL BASED_CODE _tlid =
{ 0x344B8576 , 0xAB2C , 0x4D38 , { 0xAE , 0x7 , 0x73 , 0x74 , 0x22 , 0x89 , 0x72 , 0xEA } };
const WORD _wVerMajor = 1 ;
const WORD _wVerMinor = 0 ;
// CActivexDemoApp::InitInstance - DLL 初始化
BOOL CActivexDemoApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
// TODO: 在此添加您自己的模块初始化代码。
}
return bInit;
}
// CActivexDemoApp::ExitInstance - DLL 终止
int CActivexDemoApp::ExitInstance()
{
// TODO: 在此添加您自己的模块终止代码。
return COleControlModule::ExitInstance();
}
// 创建组件种类
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;
}
// 注册组件种类
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;
}
STDAPI DllRegisterServer( void )
{
HRESULT hr;
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(BASED_CODE _tlid , CATID_SafeForInitializing);
if (FAILED(hr)) return hr;
// 标记控件脚本安全
// 创建脚本安全组件种类
hr = CreateComponentCategory(CATID_SafeForScripting, L " Controls safely scriptable! " );
if (FAILED(hr)) return hr;
// 注册脚本安全组件种类
hr = RegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);
if (FAILED(hr)) return hr;
return NOERROR;
}
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer( void )
{
HRESULT hr;
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(BASED_CODE _tlid , CATID_SafeForInitializing);
if (FAILED(hr)) return hr;
// 删除控件脚本安全入口
hr = UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);
if (FAILED(hr)) return hr;
return NOERROR;
}
现在控件就可以在自注册时就注册为安全控件了。
2、设置项目属性 将配置类型设置成静态库(.lib)
3、 最后生成项目,ocx控件就产生了。