#include <objsafe.h>//OCX控件在IE8浏览器下不能使用问题
一、OCX控件开发常见的问题
1、OCX控件在IE8浏览器下不能使用问题
原因:IE8会拦截OCX控件的方法。
解决方法:在OCX控件开发时加入安全接口。
(1)在有”Crtl“字样的头文件”.h“中加入如下代码:
- #include <objsafe.h>

#include <objsafe.h>
并在头文件类的内部加入如下安全接口,代码如下:
- //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

//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“为本例的类名,加入到你代码中请注意替换。
- 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);
- }

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“的字样的头文件上加入如下三个函数声明及一个鼠标事件。
- virtual BOOL OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult);
- HRESULT OnActivateInPlace(BOOL bUIActivate, LPMSG pMsg);
- 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文件中加入如下代码:
- 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);
- }

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);
}
并加入鼠标事件处理:
- 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);
- }

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事件上也加上
- OnActivateInPlace(TRUE, NULL);

OnActivateInPlace(TRUE, NULL);
该代码,记得在你的对话框创建前。
3、其他一些问题如果你遇上了,请看一下下面一篇博文,看看是不是有解决方案在其中。博文地址:http://blog.csdn.NET/xiaoxiaoyu85/article/details/6821205
#include <objsafe.h>//OCX控件在IE8浏览器下不能使用问题的更多相关文章
- VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程
开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是总结了网上好多人写的文章,我只是汇总一下,加上部分自己的东西,在这里感谢所有在网 ...
- ocx控件避免弹出警告的类--2
本文与 OCX控件避免弹出安全警告的类 http://www.cnblogs.com/lidabo/archive/2013/03/26/2981852.html 有些类似,只不过增加了几行代码(红色 ...
- html 调用ocx控件
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/x ...
- 调用ocx ActiveX控件详解(做一个简单的ocx控件)
背景 最近做的项目都和插件有关,就是在页面中调用插件的方法,然后进行操作. 插件就是ocx ActiveX控件,具体的说明可以自己去了解一下,在这里就不做赘述. 具体调用方式很简单: 1.在页面中写一 ...
- 帮同事写了几行代码,在 安装/卸载 程序里 注册/卸载 OCX控件
写了个小控制台程序,这个程序用来注册 / 卸载OCX控件,用在Inno Setup做的安装卸载程序里. #include "stdafx.h" #include <windo ...
- OCX控件避免弹出安全警告的类
1.要加一个头文件: #include <objsafe.h>2.在控件头文件中加入: 1 DECLARE_INTERFACE_MAP()2 BEGIN_INTERFACE ...
- MFC中开发ocx控件,html容器收不到ocx的事件Event
问题背景: MFC开发ocx控件,主窗口就是ctrl类,主窗口类中调度接口和事件映射添加,执行OK,外部html容器中接收事件成功,如下: ctrl.h中声明事件映射函数 void EVTPENSIG ...
- PHP调用OCX控件的具体方法
需要设置php.ini文件,找到这行com.allow_dcom=true,把com组件支持启用 使用PHP调用OCX控件,本不是个难题,但现实中采用flash回避的方法更通用.真正使用ocx的不多, ...
- ocx控件针对网页刷新和关闭分别进行区分处理
当ocx加载在网页上时,如果对网页执行F5刷新事件,ocx控件会销毁ocx的窗口类,但是ocx的APP类是不会销毁的. 只有当网页被关闭时,才销毁app类. --------------------- ...
随机推荐
- MySql数据库忘记root密码
以windows为例: 1. 关闭正在运行的MySQL服务.(services.msc运行停止服务) 2. 打开DOS窗口,转到mysql\bin目录.(输入cd..返回到c盘根目录下,一般MySQL ...
- 如何使用花生壳 发布WCF服务 进行外网访问
当我们发布WCF服务的时候,可以直接通过服务器的域名或者IP进行. 但是如果仅仅是通过花生壳进行域名解析,需要我们自己在设置的时候注意以下几点, 直接用图说明问题 1.首先配置花生壳,在红色处填写一个 ...
- C#编程语言与面向对象——类与对象
由于ASP.NET技术是全面向对象的,因此,要掌握这一技术,必须具备有扎实的面向对象理论基础 使用C#编程,所有的程序代码几乎都放在类中,不存在独立于类中之外的函数,因此,类是面向对象编程的基本单元 ...
- myeclipse10中文注释乱码问题
将别人的项目或JAVA文件导入到自己的Eclipse中时,常常会出现JAVA文件的中文注释变成乱码的情况,主要原因就是别人的IDE编码格式和自己的Eclipse编码格式不同. 总结网上的建议和自己的体 ...
- jquery的ajax和jsonp的写法
交互 ajax jsonp ajax跟之前一模一样 $(document).ready(function(){ $.ajax({ url:'get.php', ...
- Html菜鸡大杂烩
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Swift处理堆栈问题——给定两组序列,其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序
题目:输入两个整数序列.其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序.为了简单起见,我们假设push 序列的任意两个整数都是不相等的.比如输入的push 序列是1. ...
- Your stream was neither an OLE2 stream, nor an OOXML stream.问题的解决
先说说问题的来源 ,使用NPOI读取Except,先通过流来读取,如果符合要求,就将流保存为文件. 众所周知,流只能读一次,所以在流读取之前需要将流拷贝一份,保存文件的时候使用. protected ...
- I2C
1.I2C协议个. 2.1 I2CADR 地址寄存器CPU也可以是I2C的Slave,CPU的I2C地址有 I2CADR指定 2.2 I2CFDR 频率设置寄存器The serial bit cloc ...
- eclipse连接mysql,插入数据时乱码
问题:如果eclipse中项目的编码方式为utf-8 插入数据后,在数据库中查看后,汉字出现乱码情况 解决方法: 1.在获取连接的时候将conn = DriverManager.getConnecti ...