源码下载
参考
在代码中实现IObjectSafety接口,以去除IE对代码未标识安全的提示
在“<工程名>Ctrl.h”中
引入头文件
#include <ObjSafe.h>
在“DECLARE_DYNCREATE(C<工程名>Ctrl)”语句下面添加
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);
在“<工程名>Ctrl.cpp”中的UpdateRegistry方法后加入
///////////////////////////////////////////////////////////////////////////// // Interface map for IObjectSafety BEGIN_INTERFACE_MAP( C<工程名>Ctrl, COleControl ) INTERFACE_PART(C<工程名>Ctrl, IID_IObjectSafety, ObjSafe) END_INTERFACE_MAP() ///////////////////////////////////////////////////////////////////////////// // IObjectSafety member functions // Delegate AddRef, Release, QueryInterface ULONG FAR EXPORT C<工程名>Ctrl::XObjSafe::AddRef() { METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe) return pThis->ExternalAddRef(); } ULONG FAR EXPORT C<工程名>Ctrl::XObjSafe::Release() { METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe) return pThis->ExternalRelease(); } HRESULT FAR EXPORT C<工程名>Ctrl::XObjSafe::QueryInterface( REFIID iid, void FAR* FAR* ppvObj) { METHOD_PROLOGUE(C<工程名>Ctrl, 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 C<工程名>Ctrl::XObjSafe::GetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions, /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions) { METHOD_PROLOGUE(C<工程名>Ctrl, 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 } ///////////////////////////////////////////////////////////////////////////// // 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 C<工程名>Ctrl::XObjSafe::SetInterfaceSafetyOptions( /* [in] */ REFIID riid, /* [in] */ DWORD dwOptionSetMask, /* [in] */ DWORD dwEnabledOptions) { METHOD_PROLOGUE(C<工程名>Ctrl, 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); }
说明
- 本solution中建了一个ActiveX控件,与3个测试容器分别为C#、C++、HTML,见截图:
- vs2012中方法与属性在MyMFCActiveXControlLib/_DMyMFCActiveXControl右击添加,事件则在CMyMFCActiveXControlCtrl中添加
- vs2012中在属性页中添加新控件并为其关联属性时无“Optional property name”,必须在DoDataExchange中用DDP_Text手动关联控件变量
// CMyMFCActiveXControlPropPage::DoDataExchange - 在页和属性间移动数据 void CMyMFCActiveXControlPropPage::DoDataExchange(CDataExchange* pDX) { DDP_Text(pDX, IDC_EDIT_INTERVAL, m_updateInterval,L"Interval"); DDX_Text(pDX, IDC_EDIT_INTERVAL, m_updateInterval); DDP_PostProcessing(pDX); }
- 在ActiveX控件的工程属性页设置使用IE进行调试后,直接按F5进行调试的话由于IE新建进程打开此HTML页而使得无法进入断点,应该为VS附加至目标iexplorer进程
- c#容器工程测试运行时抛“未处理COMException”,生成的目标平台设为“x86”即可
- 在本地上打开html页进行测试时,ActiveX会自动注册