转载地址:

http://blog.csdn.net/iaki2008/article/details/8727704


源码下载



参考

在代码中实现IObjectSafety接口,以去除IE对代码未标识安全的提示

在“<工程名>Ctrl.h”中

引入头文件

[cpp]  view plain copy
  1. #include <ObjSafe.h>  


在“DECLARE_DYNCREATE(C<工程名>Ctrl)”语句下面添加

[cpp]  view plain copy
  1. DECLARE_INTERFACE_MAP()  
  2. BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)   
  3. STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (   
  4.      /* [in] */ REFIID riid,   
  5.      /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,   
  6.      /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions   
  7. );   
  8.            
  9. STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (   
  10.      /* [in] */ REFIID riid,   
  11.      /* [in] */ DWORD dwOptionSetMask,   
  12.      /* [in] */ DWORD dwEnabledOptions   
  13. );   
  14. END_INTERFACE_PART(ObjSafe);  


在“<工程名>Ctrl.cpp”中的UpdateRegistry方法后加入

[cpp]  view plain copy
  1.   
  2. // Interface map for IObjectSafety  
  3. BEGIN_INTERFACE_MAP( C<工程名>Ctrl, COleControl )   
  4. INTERFACE_PART(C<工程名>Ctrl, IID_IObjectSafety, ObjSafe)   
  5. END_INTERFACE_MAP()  
  6.   
  7. // IObjectSafety member functions  
  8. // Delegate AddRef, Release, QueryInterface  
  9. ULONG FAR EXPORT C<工程名>Ctrl::XObjSafe::AddRef()   
  10. {   
  11.     METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe)   
  12.     return pThis->ExternalAddRef();   
  13. }  
  14. ULONG FAR EXPORT C<工程名>Ctrl::XObjSafe::Release()   
  15. {   
  16.     METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe)   
  17.     return pThis->ExternalRelease();   
  18. }  
  19. HRESULT FAR EXPORT C<工程名>Ctrl::XObjSafe::QueryInterface(   
  20.     REFIID iid, void FAR* FAR* ppvObj)   
  21. {   
  22.     METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe)   
  23.     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);   
  24. }  
  25. const DWORD dwSupportedBits =   
  26. INTERFACESAFE_FOR_UNTRUSTED_CALLER |   
  27. INTERFACESAFE_FOR_UNTRUSTED_DATA;   
  28. const DWORD dwNotSupportedBits = ~ dwSupportedBits;   
  29.   
  30.   
  31.   
  32. // CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions   
  33. // Allows container to query what interfaces are safe for what. We're   
  34. // optimizing significantly by ignoring which interface the caller is   
  35. // asking for.   
  36. HRESULT STDMETHODCALLTYPE   
  37. C<工程名>Ctrl::XObjSafe::GetInterfaceSafetyOptions(   
  38. /* [in] */ REFIID riid,   
  39.         /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,   
  40.         /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)   
  41. {   
  42. METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe)  
  43. HRESULT retval = ResultFromScode(S_OK);  
  44. // does interface exist?   
  45. IUnknown FAR* punkInterface;   
  46. retval = pThis->ExternalQueryInterface(&riid,   
  47.      (void * *)&punkInterface);   
  48. if (retval != E_NOINTERFACE) { // interface exists   
  49. punkInterface->Release(); // release it--just checking!   
  50. }   
  51.   
  52.   
  53. // we support both kinds of safety and have always both set,   
  54. // regardless of interface   
  55. *pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;  
  56. return retval; // E_NOINTERFACE if QI failed   
  57. }  
  58.   
  59. // CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions   
  60. // Since we're always safe, this is a no-brainer--but we do check to make   
  61. // sure the interface requested exists and that the options we're asked to   
  62. // set exist and are set on (we don't support unsafe mode).   
  63. HRESULT STDMETHODCALLTYPE   
  64. C<工程名>Ctrl::XObjSafe::SetInterfaceSafetyOptions(   
  65.         /* [in] */ REFIID riid,   
  66.         /* [in] */ DWORD dwOptionSetMask,   
  67.         /* [in] */ DWORD dwEnabledOptions)   
  68. {   
  69.     METHOD_PROLOGUE(C<工程名>Ctrl, ObjSafe)   
  70.   
  71.   
  72. // does interface exist?   
  73. IUnknown FAR* punkInterface;   
  74. pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);   
  75. if (punkInterface) { // interface exists   
  76. punkInterface->Release(); // release it--just checking!   
  77. }   
  78. else { // interface doesn't exist   
  79. return ResultFromScode(E_NOINTERFACE);   
  80. }  
  81. // can't set bits we don't support   
  82. if (dwOptionSetMask & dwNotSupportedBits) {   
  83. return ResultFromScode(E_FAIL);   
  84. }   
  85.   
  86.   
  87. // can't set bits we do support to zero   
  88. dwEnabledOptions &= dwSupportedBits;   
  89. // (we already know there are no extra bits in mask )   
  90. if ((dwOptionSetMask & dwEnabledOptions) !=   
  91.    dwOptionSetMask) {   
  92. return ResultFromScode(E_FAIL);   
  93. }          
  94.   
  95.   
  96. // don't need to change anything since we're always safe   
  97. return ResultFromScode(S_OK);   
  98. }  


说明

  • 本solution中建了一个ActiveX控件,与3个测试容器分别为C#、C++、HTML,见截图:

  • vs2012中方法与属性在MyMFCActiveXControlLib/_DMyMFCActiveXControl右击添加,事件则在CMyMFCActiveXControlCtrl中添加
  • vs2012中在属性页中添加新控件并为其关联属性时无“Optional property name”,必须在DoDataExchange中用DDP_Text手动关联控件变量

[cpp]  view plain copy
  1. // CMyMFCActiveXControlPropPage::DoDataExchange - 在页和属性间移动数据  
  2.   
  3. void CMyMFCActiveXControlPropPage::DoDataExchange(CDataExchange* pDX)  
  4. {  
  5.     DDP_Text(pDX, IDC_EDIT_INTERVAL, m_updateInterval,L"Interval");  
  6.     DDX_Text(pDX, IDC_EDIT_INTERVAL, m_updateInterval);  
  7.     DDP_PostProcessing(pDX);  
  8. }  


  • 在ActiveX控件的工程属性页设置使用IE进行调试后,直接按F5进行调试的话由于IE新建进程打开此HTML页而使得无法进入断点,应该为VS附加至目标iexplorer进程

  • c#容器工程测试运行时抛“未处理COMException”,生成的目标平台设为“x86”即可

  • 在本地上打开html页进行测试时,ActiveX会自动注册

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐