一、OCX控件开发常见的问题

1、OCX控件在IE8浏览器下不能使用问题

原因:IE8会拦截OCX控件的方法。

解决方法:在OCX控件开发时加入安全接口。

(1)在有”Crtl“字样的头文件”.h“中加入如下代码:

  1. #include <objsafe.h>
        #include <objsafe.h> 

并在头文件类的内部加入如下安全接口,代码如下:

  1. //ISafeObject
  2. DECLARE_INTERFACE_MAP()
  3. BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
  4. STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (
  5. /* [in] */ REFIID riid,
  6. /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
  7. /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
  8. );
  9. STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (
  10. /* [in] */ REFIID riid,
  11. /* [in] */ DWORD dwOptionSetMask,
  12. /* [in] */ DWORD dwEnabledOptions
  13. );
  14. END_INTERFACE_PART(ObjSafe);
  15. //ISafeObject
//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

(2)在有”Ctrl“字样的CPP文件中添加如下代码:注下面类名这里都以”CxxxCtrl“为本例的类名,加入到你代码中请注意替换。

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

如果加安全代码后,还是不能正常加载,那你要确认一下,你的操作系统是64位系统吗?若是,再看一下你IE是不是也使用64位的。若是的话,那就没有办法了,我在前面的博文中已经说明了,64位的IE是不支持32位OCX控件,请使用更高的IE版本调试或者。。。建议使用IE10及以上,IE9也同样存在这样的问题。如果不是,那你再看一下找一下其他原因,或者在评论中阐述你的问题出现的现象,博友们一起帮你研究与解决。

2、OCX控件引入对话框界面后,OCX控件无法响应键盘”backspack“键。

原因:IE浏览器截获该事件,出现一按”backpack“键,网页就回退,无法正常在OCX控件上操作。

解决方法:有两种,一使用MFC中的钩子方法(不推荐,本文不详细解说),另一种是OCX控件中添加处理事件的函数来处理,具体说明请查看官网  http://support.microsoft.com/kb/168777/nl

(1)在”Ctrl“的字样的头文件上加入如下三个函数声明及一个鼠标事件。

  1. virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
  2. HRESULT OnActivateInPlace(BOOL bUIActivate, LPMSG pMsg);
  3. BOOL PreTranslateMessage(MSG* pMsg);
	virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
HRESULT OnActivateInPlace(BOOL bUIActivate, LPMSG pMsg);
BOOL PreTranslateMessage(MSG* pMsg);

一个鼠标事件 afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);

(2)在”Ctrl“字样的CPP文件中加入如下代码:

  1. BOOL CxxxCtrl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT *pResult)
  2. {
  3. switch (message)
  4. {
  5. case WM_REPORT_BATCHWRITEPU_CLOSEFLAGE:
  6. this->FireSetCloseFlag((short)wParam);
  7. break;
  8. }
  9. return COleControl::OnWndMsg(message, wParam, lParam, pResult);
  10. }
  11. HRESULT CxxxCtrl::OnActivateInPlace(BOOL bUIActivate, LPMSG pMsg)
  12. {
  13. static BOOL bInsideFunc = FALSE;
  14. if (!bInsideFunc)
  15. {
  16. bInsideFunc = TRUE;
  17. HRESULT hr = COleControl::OnActivateInPlace(bUIActivate, pMsg);
  18. bInsideFunc = FALSE;
  19. return hr;
  20. }
  21. return S_OK;
  22. }
  23. BOOL CxxxCtrl::PreTranslateMessage(MSG* pMsg)
  24. {
  25. switch (pMsg->message)
  26. {
  27. case WM_KEYDOWN:
  28. case WM_KEYUP:
  29. switch (pMsg->wParam)
  30. {
  31. case VK_UP:
  32. case VK_DOWN:
  33. case VK_LEFT:
  34. case VK_RIGHT:
  35. case VK_HOME:
  36. case VK_END:
  37. ::SendMessage (GetFocus()->GetSafeHwnd(), pMsg->message, pMsg->wParam, pMsg->lParam);
  38. return TRUE;
  39. }
  40. break;
  41. }
  42. return COleControl::PreTranslateMessage(pMsg);
  43. }
BOOL CxxxCtrl::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT *pResult)
{
switch (message)
{
case WM_REPORT_BATCHWRITEPU_CLOSEFLAGE:
this->FireSetCloseFlag((short)wParam);
break;
}
return COleControl::OnWndMsg(message, wParam, lParam, pResult);
}
HRESULT CxxxCtrl::OnActivateInPlace(BOOL bUIActivate, LPMSG pMsg)
{
static BOOL bInsideFunc = FALSE;
if (!bInsideFunc)
{
bInsideFunc = TRUE;
HRESULT hr = COleControl::OnActivateInPlace(bUIActivate, pMsg);
bInsideFunc = FALSE;
return hr;
}
return S_OK;
}
BOOL CxxxCtrl::PreTranslateMessage(MSG* pMsg)
{
switch (pMsg->message)
{
case WM_KEYDOWN:
case WM_KEYUP:
switch (pMsg->wParam)
{
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
case VK_HOME:
case VK_END:
::SendMessage (GetFocus()->GetSafeHwnd(), pMsg->message, pMsg->wParam, pMsg->lParam);
return TRUE;
}
break;
}
return COleControl::PreTranslateMessage(pMsg);
}

并加入鼠标事件处理:

  1. int <span style="font-family: Arial, Helvetica, sans-serif;">CxxxCtrl</span>::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
  2. {
  3. // TODO: Add your message handler code here and/or call default
  4. OnActivateInPlace(TRUE, NULL); //事件加入后,请加入此行代码。
  5. return COleControl::OnMouseActivate(pDesktopWnd, nHitTest, message);
  6. }
int <span style="font-family: Arial, Helvetica, sans-serif;">CxxxCtrl</span>::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
OnActivateInPlace(TRUE, NULL); //事件加入后,请加入此行代码。
return COleControl::OnMouseActivate(pDesktopWnd, nHitTest, message);
}

并OnCreate事件上也加上

  1. OnActivateInPlace(TRUE, NULL);
OnActivateInPlace(TRUE, NULL); 

该代码,记得在你的对话框创建前。

3、其他一些问题如果你遇上了,请看一下下面一篇博文,看看是不是有解决方案在其中。博文地址:http://blog.csdn.NET/xiaoxiaoyu85/article/details/6821205

#include <objsafe.h>//OCX控件在IE8浏览器下不能使用问题的更多相关文章

  1. VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程

      开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是总结了网上好多人写的文章,我只是汇总一下,加上部分自己的东西,在这里感谢所有在网 ...

  2. ocx控件避免弹出警告的类--2

    本文与 OCX控件避免弹出安全警告的类 http://www.cnblogs.com/lidabo/archive/2013/03/26/2981852.html 有些类似,只不过增加了几行代码(红色 ...

  3. html 调用ocx控件

    !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/x ...

  4. 调用ocx ActiveX控件详解(做一个简单的ocx控件)

    背景 最近做的项目都和插件有关,就是在页面中调用插件的方法,然后进行操作. 插件就是ocx ActiveX控件,具体的说明可以自己去了解一下,在这里就不做赘述. 具体调用方式很简单: 1.在页面中写一 ...

  5. 帮同事写了几行代码,在 安装/卸载 程序里 注册/卸载 OCX控件

    写了个小控制台程序,这个程序用来注册 / 卸载OCX控件,用在Inno Setup做的安装卸载程序里. #include "stdafx.h" #include <windo ...

  6. OCX控件避免弹出安全警告的类

    1.要加一个头文件:         #include <objsafe.h>2.在控件头文件中加入: 1 DECLARE_INTERFACE_MAP()2 BEGIN_INTERFACE ...

  7. MFC中开发ocx控件,html容器收不到ocx的事件Event

    问题背景: MFC开发ocx控件,主窗口就是ctrl类,主窗口类中调度接口和事件映射添加,执行OK,外部html容器中接收事件成功,如下: ctrl.h中声明事件映射函数 void EVTPENSIG ...

  8. PHP调用OCX控件的具体方法

    需要设置php.ini文件,找到这行com.allow_dcom=true,把com组件支持启用 使用PHP调用OCX控件,本不是个难题,但现实中采用flash回避的方法更通用.真正使用ocx的不多, ...

  9. ocx控件针对网页刷新和关闭分别进行区分处理

    当ocx加载在网页上时,如果对网页执行F5刷新事件,ocx控件会销毁ocx的窗口类,但是ocx的APP类是不会销毁的. 只有当网页被关闭时,才销毁app类. --------------------- ...

随机推荐

  1. A - 迷宫问题

      Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Pra ...

  2. DNS记录类型介绍(A记录、MX记录、NS记录等)

    DNS A记录 NS记录 MX记录 CNAME记录 TXT记录 TTL值 PTR值 建站名词解释:DNS A记录 NS记录 MX记录 CNAME记录 TXT记录 TTL值 PTR值 泛域名 泛解析 域 ...

  3. Myelipcse导入Maven项目: version of spring facet could not be detected

    在导入已存在的maven web项目的时候,总是出现Versions of Spring facet could not be detected的问题. 查资料知道有两种解决方法:一个是什么在项目根目 ...

  4. HTC One M7简易刷Recovery教程

          HTC One M7作为当下HTC旗下的旗舰热门机,用户们对于刷机的需求都比较强烈,对于刷ROM的前提就是要刷入Recovery,当然作为安卓智能手机HTC one而言也不例外,最近有些用 ...

  5. 使用gnucash查看任意时间段内的所有者权益变动表

    gnucash默认会以当年的会计账期显示所有者权益变动表 如果要看指定时间的所有者权益变动表,需要这样做 打开所有者权益变动表 点击上面的[选项] 如图 在常规中自行选择日期 确定后就能够看到指定时间 ...

  6. install google chrome

    32bit: wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb sudo dpkg -i go ...

  7. hdu1087 dp

    题意:给定一串数字,要求选取一个严格递增的子序列,使序列和最大. dp[i] 表示以 i 为结尾的子序列的最大和,dp[i] = max{dp[j]+a[i]}(j 从 0 到 i-1),dp[0]是 ...

  8. 00 alv抬头等

    *&---------------------------------------------------------------------* *& Report ZHJ_TEST0 ...

  9. 查看哪些表的哪些列含有指定字符串(如‘andy’存在哪些表的哪些列中)

    -- 查看表中列含有指定字符.SQL> select * from demo1;NAME                                   ID---------------- ...

  10. mysql 5.7修改密码

    关闭正在运行的 MySQL : [root@www.woai.it ~]# service mysql stop 运行 [root@www.woai.it ~]# mysqld_safe --skip ...