MFC OCX控件实现安全初始化和脚本安全的方法
来源:互联网 发布:守望先锋 英雄详细数据 编辑:程序博客网 时间:2024/05/23 02:01
如果不实现该IObjectSafety接口,IE调用时会有如下提示信息:
解决方法有两种,如下:
方法1:通过IObjectSafety接口实现
具体步骤:
(1)在TestOCXCtrl.h中
#include <objsafe.h> // for IObjectSafety; in ActiveX SDK
(2)在TestOCXCtrl.h中
DECLARE_OLECREATE_EX(CTestOCXCtrl) // Class factory and guid
//***************************************************************add begin
//ISafeObject
DECLARE_INTERFACE_MAP()
BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
);
STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions
);
END_INTERFACE_PART(ObjSafe);
//ISafeObject
//***************************************************************add end
DECLARE_OLETYPELIB(CTestOCXCtrl) // GetTypeInfo
DECLARE_PROPPAGEIDS(CTestOCXCtrl) // Property page IDs
DECLARE_OLECTLTYPE(CTestOCXCtrl)// Type name and misc status
(3)在TestOCXCtrl.cpp中
// Message map
BEGIN_MESSAGE_MAP(CTestOCXCtrl, COleControl)
//{{AFX_MSG_MAP(CTestOCXCtrl)
// NOTE - ClassWizard will add and remove message map entries
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG_MAP
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()
//***************************************************************add begin
BEGIN_INTERFACE_MAP( CTestOCXCtrl, COleControl )
INTERFACE_PART(CTestOCXCtrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()
//***************************************************************add end
/////////////////////////////////////////////////////////////////////////////
// Dispatch map
................................
增加IObjectSafety接口实现方法
////***************************************************************add begin
// IObjectSafety member functions
// Delegate AddRef, Release, QueryInterface
ULONG FAR EXPORT CTestOCXCtrl::XObjSafe::AddRef()
{
METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CTestOCXCtrl::XObjSafe::Release()
{
METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CTestOCXCtrl::XObjSafe::QueryInterface(REFIID iid, void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;
//.............................................................................
// CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions
// Allows container to query what interfaces are safe for what. We're
// optimizing significantly by ignoring which interface the caller is
// asking for.
HRESULT STDMETHODCALLTYPE
CTestOCXCtrl::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)
HRESULT retval = ResultFromScode(S_OK);
// does interface exist?
IUnknown FAR* punkInterface;
retval = pThis->ExternalQueryInterface(&riid,
(void * *)&punkInterface);
if (retval != E_NOINTERFACE) { // interface exists
punkInterface->Release(); // release it--just checking!
}
// we support both kinds of safety and have always both set,
// regardless of interface
*pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;
return retval; // E_NOINTERFACE if QI failed
}
方法2:通过修改注册表实现,方法如下://///////////////////////////////////////////////////////////////////////////
// CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions
// Since we're always safe, this is a no-brainer--but we do check to make
// sure the interface requested exists and that the options we're asked to
// set exist and are set on (we don't support unsafe mode).
HRESULT STDMETHODCALLTYPE
CTestOCXCtrl::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
METHOD_PROLOGUE(CTestOCXCtrl, ObjSafe)
// does interface exist?
IUnknown FAR* punkInterface;
pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);
if (punkInterface) { // interface exists
punkInterface->Release(); // release it--just checking!
}
else { // interface doesn't exist
return ResultFromScode(E_NOINTERFACE);
}
// can't set bits we don't support
if (dwOptionSetMask & dwNotSupportedBits) {
return ResultFromScode(E_FAIL);
}
// can't set bits we do support to zero
dwEnabledOptions &= dwSupportedBits;
// (we already know there are no extra bits in mask )
if ((dwOptionSetMask & dwEnabledOptions) !=
dwOptionSetMask) {
return ResultFromScode(E_FAIL);
}
// don't need to change anything since we're always safe
return ResultFromScode(S_OK);
}
//***************************************************************add end
// Define the GUID associated with the safety component categories:
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}};
// 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);
// 卸载组件种类
HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
// 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 = {0};
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;
}
// 卸载组件种类
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;
}
Define the GUID associated with your control.
For simplicity, you can borrow the GUID from the IMPLEMENT_OLECREATE_EX macro in the xxxCtrl.cpp file for the control.
Adjust the format slightly so that it looks like the following:
const CATID CLSID_SafeItem =
{ 0x43bd9e45, 0x328f, 0x11d0,
{ 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
注意:此处为控件的GUID .
To mark your control as both Safe for Scripting and Initialization, modify the DllRegisterServer function as follows:
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(
CLSID_SafeItem, CATID_SafeForScripting) ))
return ResultFromScode(SELFREG_E_CLASS);
if (FAILED( RegisterCLSIDInCategory(
CLSID_SafeItem, CATID_SafeForInitializing) ))
return ResultFromScode(SELFREG_E_CLASS);
return NOERROR;
}
2 反注册时
You would not normally modify the DllUnregisterServer function for these two reasons:
(1)You would not want to remove a component category because other controls may be using it.
(2)Although there is an UnRegisterCLSIDInCategory function defined,
by default DllUnregisterServer removes the control's entry from the registry entirely.
Therefore, removing the category from the control's registration is of little use.
- MFC OCX控件实现安全初始化和脚本安全的方法
- MFC OCX控件实现安全初始化和脚本安全的方法http://blog.csdn.net/xiliang_pan/article/details/8264685
- ActiveX控件实现安全的初始化和脚本
- ActiveX控件实现安全的初始化和脚本
- ActiveX控件实现安全的初始化和脚本
- ActiveX控件实现安全的初始化和脚本
- ActiveX控件实现安全的初始化和脚本
- ActiveX控件实现安全的初始化和脚本
- ActiveX控件实现安全的初始化和脚本
- 如何将标记为可安全编写脚本和初始化的 MFC ActiveX 控件
- 如何将标记为可安全编写脚本和初始化的 MFC ActiveX 控件 (转)
- ActiveX控件的安全初始化和脚本操作
- MFC ActiveX OCX控件添加安全接口
- 如何将 MFC ActiveX 控件作为安全标记为脚本和初始化
- 如何将MFC ActiveX 控件标记为可安全编写脚本和初始化
- 如何将 MFC ActiveX 控件作为安全标记为脚本和初始化
- 如何将 MFC ActiveX 控件标记为安全,脚本和初始化
- 如何将 MFC ActiveX 控件标记为脚本和初始化安全
- 由tcpip.sys损坏引起的网络无法连接的问题
- ubuntu防火墙安装、启用、查看状态
- java实现压缩解压缩
- 概率论与数理统计知识点整理(二)条件概率和独立性
- Git使用方法(二)
- MFC OCX控件实现安全初始化和脚本安全的方法
- MySQL的几个概念:主键,外键,索引,唯一索引
- 虚拟化平台 KVM API的ioctl使用示范(一)
- pthreads —— POSIX线程 7 .
- 深入理解JVM内幕:从基本结构到Java 7新特性
- 实现RTP协议的H.264视频传输系统
- activiti5.9在windows下的使用
- js代码实现填写简历时“添加项目经历”功能
- VIM常用配置