zoukankan      html  css  js  c++  java
  • #include <objsafe.h>//OCX控件在IE8浏览器下不能使用问题

     

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

  • 相关阅读:
    重装系统后无线网卡问题
    U盘重装系统win7
    移动端高清、多屏适配方案
    javascript闭包
    javascript的this指向
    合作开发,导入MyEclipse项目报错问题
    [LC] 117. Populating Next Right Pointers in Each Node II
    [LC] 443. String Compression
    [LC] 1099. Two Sum Less Than K
    [LC] 149. Max Points on a Line
  • 原文地址:https://www.cnblogs.com/andyliu1988/p/6084444.html
Copyright © 2011-2022 走看看