none
请教一下,如何屏蔽脚本错误(com技术) RRS feed

  • 问题

  • 自己做的浏览器,用CHtmlView类做的,打开新页面用OnNewWindow2方法

    有些网站打开时都会报IE的脚本错误.我想请教一下,如何在我的浏览器屏蔽错误提示.

    我想知道,如何一步一步地按下面方法添加,COM一点不会,但这个应该是非常好的解决方法
    麻烦各位了~~

    这是微软的解决方案:http://support.microsoft.com/kb/261003/zh-cn

    STDMETHODIMP CMyBrowser::Exec( const GUID* pguidCmdGroup, DWORD nCmdID,
    DWORD nCmdexecopt, VARIANTARG* pvaIn, VARIANTARG* pvaOut )
    {
        HRESULT hr = S_OK;
        
        if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
        {
            switch (nCmdID)
            {
                case OLECMDID_SHOWSCRIPTERROR:
                {
                    IHTMLDocument2*             pDoc = NULL;
                    IHTMLWindow2*               pWindow = NULL;
                    IHTMLEventObj*              pEventObj = NULL;
                    BSTR                        rgwszNames[5] =
                      {  SysAllocString(L"errorLine"),
                         SysAllocString(L"errorCharacter"),
                         SysAllocString(L"errorCode"),
                         SysAllocString(L"errorMessage"),
                         SysAllocString(L"errorUrl")          };
                    DISPID                      rgDispIDs[5];
                    VARIANT                     rgvaEventInfo[5];
                    DISPPARAMS                  params;
                    BOOL                        fContinueRunningScripts = true;
                    int                            i;
                    
                    params.cArgs = 0;
                    params.cNamedArgs = 0;
    
                    hr = pvaIn->punkVal->QueryInterface(IID_IHTMLDocument2, (void **) &pDoc);                
    
                    hr = pDoc->get_parentWindow(&pWindow);
                    pDoc->Release();
    
                    hr = pWindow->get_event(&pEventObj);
    
                    for (i = 0; i < 5; i++)
                    {
                        // Get the property's dispID.
                        hr = pEventObj->GetIDsOfNames(IID_NULL, &rgwszNames[i], 1,
                        LOCALE_SYSTEM_DEFAULT, &rgDispIDs[i]);
                        // Get the value of the property.
                        hr = pEventObj->Invoke(rgDispIDs[i], IID_NULL,
                        LOCALE_SYSTEM_DEFAULT,
                        DISPATCH_PROPERTYGET, &params, &rgvaEventInfo[i],
                        NULL, NULL);
                        SysFreeString(rgwszNames[i]);
                    }
                    (*pvaOut).vt = VT_BOOL;
                    if (fContinueRunningScripts)//这一行不是多余的?因为fContinueRunningScripts为真
                    {
                        // Continue running scripts on the page.
                        (*pvaOut).boolVal = VARIANT_TRUE;
                    }
                    else
                    {
                        // Stop running scripts on the page.
                        (*pvaOut).boolVal = VARIANT_FALSE;            
                    }
                    break;
                }
                default:
                hr = OLECMDERR_E_NOTSUPPORTED;
                break;
            }
        }
        else
        {
            hr = OLECMDERR_E_UNKNOWNGROUP;
        }
        return (hr);
    }
    
    2009年7月22日 9:02

答案

  • 很久很久没有写C++代码了,下面的代码你看看是否可以使用:

    定义一个CCustomControlSite类,从COleControlSite继承下来:

    CustomControlSite.h:

    #pragma once
    #include "afxocc.h"
    
    class CCustomControlSite : public COleControlSite
    {
    public:
    	CCustomControlSite(COleControlContainer *pCnt):COleControlSite(pCnt){}
    
    protected:
    	DECLARE_INTERFACE_MAP()
    
    	BEGIN_INTERFACE_PART(OleCommandTarget, IOleCommandTarget)
    		STDMETHOD_(HRESULT, QueryStatus)(const GUID* pguidCmdGroup,
    		                                 ULONG cCmds,        
    					     OLECMD *prgCmds,    
    					     OLECMDTEXT *pCmdText);
    		STDMETHOD_(HRESULT, Exec)(const GUID* pguidCmdGroup, 
    		                          DWORD nCmdID,
    		                          DWORD nCmdexecopt, 
    				        VARIANTARG* pvaIn, 
    				        VARIANTARG* pvaOut);
    	END_INTERFACE_PART(OleCommandTarget)
    };
    

     

    CustomControlSite.cpp:
    #include "stdafx.h"
    #include "CustomControlSite.h"
    
    BEGIN_INTERFACE_MAP(CCustomControlSite, COleControlSite)
    	INTERFACE_PART(CCustomControlSite, IID_IOleCommandTarget, OleCommandTarget)
    END_INTERFACE_MAP()
    
    ULONG FAR EXPORT CCustomControlSite::XOleCommandTarget::AddRef()
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return pThis->ExternalAddRef();
    }
    
    ULONG FAR EXPORT CCustomControlSite::XOleCommandTarget::Release()
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return pThis->ExternalRelease();
    }
    
    HRESULT FAR EXPORT CCustomControlSite::XOleCommandTarget::QueryInterface(
    	REFIID iid, void FAR* FAR* ppvObj)
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
    }
    
    HRESULT FAR EXPORT CCustomControlSite::XOleCommandTarget::QueryStatus(
    	const GUID* pguidCmdGroup,
    	ULONG cCmds,    						 
    	OLECMD *prgCmds,    
    	OLECMDTEXT *pCmdText)
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return S_OK;
    }
    
    HRESULT FAR EXPORT CCustomControlSite::XOleCommandTarget::Exec(
    	const GUID* pguidCmdGroup, 
    	DWORD nCmdID,
    	DWORD nCmdexecopt, 
    	VARIANTARG* pvaIn, 
    	VARIANTARG* pvaOut)
    {
    	HRESULT hr = S_OK;
    
    	if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
    	{
    
    		switch (nCmdID) 
    		{
    
    		case OLECMDID_SHOWSCRIPTERROR:
    			{
    				// Continue running scripts on the page.
    				(*pvaOut).boolVal = VARIANT_TRUE;
    				break;
    			}
    		default:
    			hr = OLECMDERR_E_NOTSUPPORTED;
    			break;
    		}
    	}
    	else
    	{
    		hr = OLECMDERR_E_UNKNOWNGROUP;
    	}
    	return (hr);
    }
    然后将CHtmlView::CreateSite函数重载,代码:

    BOOL CMfcieView::CreateControlSite(COleControlContainer *pContainer,
    								   COleControlSite **ppSite,
    								   UINT nId,
    								   REFCLSID clsid)
    {
    	*ppSite = new CCustomControlSite(this->GetControlContainer());
    	return TRUE;
    }
    

    上面的CMfcieView的定义:

    class CMfcieView : public CHtmlView
    {
    ...
    public:
    	virtual BOOL CreateControlSite(COleControlContainer* pContainer, 
    	   COleControlSite** ppSite, UINT nID, REFCLSID clsid);
    ...
    };
    
    • 已编辑 Killmyday 2009年7月24日 7:31 修改格式
    • 已标记为答案 flyskytoday 2009年7月28日 3:15
    2009年7月24日 7:28

全部回复

  • 在浏览器的Internet选项里,高级页签里,有一个禁止报告脚本错误的勾选项.你要做的就是把这个设置的编程方法找到来就可以,应该在注册表里面改一个键值就可以了.

    2009年7月22日 16:20
  • 大哥,你没好好看呀。。。上面我是说
    非IE,自己做的浏览器
    ........................................
    自己做的浏览器,用CHtmlView类做的,打开新页面用OnNewWindow2方法

    有些网站打开时都会报IE的脚本错误.我想请教一下,如何在我的浏览器屏蔽错误提示.
    2009年7月23日 1:07
  • 真的谢谢,这篇文章我也看过,嵌入脚本屏蔽错误,我怕多次调用OnNavigateComplete2会出现意外错误,放在银行大厅里用的。还是想按微软提供的接口来屏蔽
    2009年7月23日 3:24
  • 这个世界上只有4个浏览器,一个是IE,一个是Netscape,一个是FireFox,另外一个是Opera,其他的所谓的自定义的,比如遨游、腾迅的浏览器,或者什么CHtmlView,Winform和WPF里面的什么WebBrowser,甚至是资源管理器,用的都是一个内核--IE的内核。

    苹果机上的Safari浏览器的内核是Mozilla--跟FireFox同宗。
    2009年7月23日 4:23
  • 关于自定义MFC中的HTML类,实现IOleCommandTarget的示例,参考http://blog.joycode.com/jiangsheng/archive/2005/07/09/58754.aspx

    Please mark the post answered your question as the answer, and click the chartreuse pyramid floating over "Vote as helpful" to mark other helpful posts as helpful. This posting is provided "AS IS" with no warranties, and confers no rights.
    Visual C++ MVP
    2009年7月23日 5:22
    版主
  • 哦,对不起,我是没有仔细看你的问题

    看起来你自己定义的WebBrowser需要实现一个接口: IOleCommandTarget,在MFC里面在你的类里面添加这个接口的支持可以参照:
    http://msdn.microsoft.com/en-us/library/aa229395(VS.60).aspx

    然后你就可以在IOleCommandTarget里面实现你的Exec函数了。如果你还有问题的话,请告诉我,我有空帮你试一下。

    2009年7月23日 5:27
  • 老大,我细细看了你的帖子,但现在还是不明白,如何一肯一步在MFC中加入IOleCommandTarget方法
    自己看了MYIE的源码,仿照加入,但不行的
    2009年7月23日 7:08
  • 很久很久没有写C++代码了,下面的代码你看看是否可以使用:

    定义一个CCustomControlSite类,从COleControlSite继承下来:

    CustomControlSite.h:

    #pragma once
    #include "afxocc.h"
    
    class CCustomControlSite : public COleControlSite
    {
    public:
    	CCustomControlSite(COleControlContainer *pCnt):COleControlSite(pCnt){}
    
    protected:
    	DECLARE_INTERFACE_MAP()
    
    	BEGIN_INTERFACE_PART(OleCommandTarget, IOleCommandTarget)
    		STDMETHOD_(HRESULT, QueryStatus)(const GUID* pguidCmdGroup,
    		                                 ULONG cCmds,        
    					     OLECMD *prgCmds,    
    					     OLECMDTEXT *pCmdText);
    		STDMETHOD_(HRESULT, Exec)(const GUID* pguidCmdGroup, 
    		                          DWORD nCmdID,
    		                          DWORD nCmdexecopt, 
    				        VARIANTARG* pvaIn, 
    				        VARIANTARG* pvaOut);
    	END_INTERFACE_PART(OleCommandTarget)
    };
    

     

    CustomControlSite.cpp:
    #include "stdafx.h"
    #include "CustomControlSite.h"
    
    BEGIN_INTERFACE_MAP(CCustomControlSite, COleControlSite)
    	INTERFACE_PART(CCustomControlSite, IID_IOleCommandTarget, OleCommandTarget)
    END_INTERFACE_MAP()
    
    ULONG FAR EXPORT CCustomControlSite::XOleCommandTarget::AddRef()
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return pThis->ExternalAddRef();
    }
    
    ULONG FAR EXPORT CCustomControlSite::XOleCommandTarget::Release()
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return pThis->ExternalRelease();
    }
    
    HRESULT FAR EXPORT CCustomControlSite::XOleCommandTarget::QueryInterface(
    	REFIID iid, void FAR* FAR* ppvObj)
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
    }
    
    HRESULT FAR EXPORT CCustomControlSite::XOleCommandTarget::QueryStatus(
    	const GUID* pguidCmdGroup,
    	ULONG cCmds,    						 
    	OLECMD *prgCmds,    
    	OLECMDTEXT *pCmdText)
    {
    	METHOD_PROLOGUE(CCustomControlSite, OleCommandTarget)
    		return S_OK;
    }
    
    HRESULT FAR EXPORT CCustomControlSite::XOleCommandTarget::Exec(
    	const GUID* pguidCmdGroup, 
    	DWORD nCmdID,
    	DWORD nCmdexecopt, 
    	VARIANTARG* pvaIn, 
    	VARIANTARG* pvaOut)
    {
    	HRESULT hr = S_OK;
    
    	if (pguidCmdGroup && IsEqualGUID(*pguidCmdGroup, CGID_DocHostCommandHandler))
    	{
    
    		switch (nCmdID) 
    		{
    
    		case OLECMDID_SHOWSCRIPTERROR:
    			{
    				// Continue running scripts on the page.
    				(*pvaOut).boolVal = VARIANT_TRUE;
    				break;
    			}
    		default:
    			hr = OLECMDERR_E_NOTSUPPORTED;
    			break;
    		}
    	}
    	else
    	{
    		hr = OLECMDERR_E_UNKNOWNGROUP;
    	}
    	return (hr);
    }
    然后将CHtmlView::CreateSite函数重载,代码:

    BOOL CMfcieView::CreateControlSite(COleControlContainer *pContainer,
    								   COleControlSite **ppSite,
    								   UINT nId,
    								   REFCLSID clsid)
    {
    	*ppSite = new CCustomControlSite(this->GetControlContainer());
    	return TRUE;
    }
    

    上面的CMfcieView的定义:

    class CMfcieView : public CHtmlView
    {
    ...
    public:
    	virtual BOOL CreateControlSite(COleControlContainer* pContainer, 
    	   COleControlSite** ppSite, UINT nID, REFCLSID clsid);
    ...
    };
    
    • 已编辑 Killmyday 2009年7月24日 7:31 修改格式
    • 已标记为答案 flyskytoday 2009年7月28日 3:15
    2009年7月24日 7:28
  • 感谢感谢楼上的,,,得慢慢看看,明一早就要用,今天要得做出来,,,真汗~~

    2009年7月26日 5:26
  • 真难啊,不会
    下面是在CSDN发的帖子,有兴趣也看一下~
    http://topic.csdn.net/u/20090726/16/8ebc4ce1-c271-4320-b23e-61072bcc959a.html
    2009年7月26日 8:34
  • 看了CSDN的帖子,还是没有搞明白你碰到什么问题了。我贴出来的源代码你碰到什么问题了?你有邮箱吗?我把代码整个发给你瞧瞧。
    2009年7月27日 4:04
  • 谢谢楼上的兄弟,还真需要得到你的帮助呢,我的邮箱是:flyskytoday&hotmail.com  &换为@ thx
    今天一早我给出一个临时解决方案,就是定时FindWindow查找错误窗口,蒙混但还不算过关,BOSS早上看了看,说还是不行,要是看不到闪一下就好了(我当然知道不行了,但现在我想不出更好地办法呀~~~)
    2009年7月27日 6:54