none
再请问一下CHtmlView中的onnewwindow2方法,地址如何取得及屏蔽 RRS feed

  • 问题

  • 用CHtmlView做的浏览器,除了设定的网站外,其他均不做链接
    用onnewwindow2方法打开新网页,要判断一下鼠标指向的地址吧,不符合要求的点击无反应

    查看了一下OnDocumentComplete函数,其中有lpszURL地址,但这个函数是在完成之后给出地址,这个好象不符合要求

    2009年6月15日 8:42

答案

  • 这个代码看起来就是用m_bNewWindow来判断了,如果是新窗口的话就在BeforeNavigate2里面拦截CSDN的网站,m_bNewWindow在NewWindow2里面设置。
    需要改改加上根据m_bNewWindow的值隐藏窗口和关闭窗口的逻辑。

    Please mark the post answered your question as the answer, and mark other helpful posts as helpful. This posting is provided "AS IS" with no warranties, and confers no rights.
    Visual C++ MVP
    2009年6月21日 16:07
    版主

全部回复

  • OnBeforeNavigate
    MSMVP VC++
    2009年6月15日 16:56
    版主
  • 老大,我用了OnBeforeNavigate2方法,可以取得地址
    OnBeforeNavigate2(LPCTSTR lpszURL,
                DWORD nFlags,
                LPCTSTR lpszTargetFrameName,
                CByteArray& baPostedData,
                LPCTSTR lpszHeaders,
                BOOL* pbCancel)
    以下是我这样做的
    if(lpszURL过滤出不符合要求的网址)
    *pbCancel=true;

    但现在有个新问题,就是即使过滤了地址但也出来一个新窗口,只是空白的窗口,我尝试着发送一个关闭消息
    GetParent()->SendMessage(WM_CLOSE);

    this->SendMessage(WM_CLOSE);

    SendMessage(WM_CLOSE,0,0);
    然后程序就莫名退出

    现在不知道,如何不让这个空白窗口打开

    2009年6月16日 2:19
  • 出一个隐藏的窗口先
    MSMVP VC++
    2009年6月16日 2:33
    版主
  • 隐藏窗口这个方法不是很好的选择吧?
    跟踪发现
    OnNewWindow2在OnBeforeNavigate2之前
    就是框架已建立后,再看看地址是否合法,需要打开?
    查了OnBeforeNavigate2事件,里面好象没有关闭的说明

    用Spy++查看窗口,父窗口和子窗口都一样,只有前面的地址不一样

    要关闭此窗口还真不容易

    PS:Spy++不太会用

    2009年6月16日 3:15
  • NewWindow2里面看不到新窗口的URL,需要到BeforeNavigate2的时候才知道。
    关闭的话发WM_COMMAND,传ID_FILE_CLOSE
    MSMVP VC++
    2009年6月16日 3:51
    版主
  • 老大,,,下面是人家回复我的,我看了半天好象也没有什么屏幕好方法,你看看是不是这样的? C/C++ code #pragma once #include // CHtmlCtrl Html 视图 class CHtmlCtrl : public CHtmlView { DECLARE_DYNCREATE(CHtmlCtrl) public: CHtmlCtrl(BOOL bNewWindow = FALSE);; // 动态创建所使用的受保护的构造函数 virtual ~CHtmlCtrl(){ }; BOOL CreateFromStatic(UINT nID, CWnd* pParent); public: #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif BOOL m_bNewWindow; CHtmlCtrl * m_pHtmlCtrlHandleNewWindow; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: virtual void OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel); afx_msg void OnDestroy(); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnSize(UINT nType, int cx, int cy); virtual void OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel); protected: virtual void PostNcDestroy(); }; C/C++ code // HtmlCtrl.cpp : 实现文件 // #include "stdafx.h" #include "HtmlCtrl.h" // CHtmlCtrl IMPLEMENT_DYNCREATE(CHtmlCtrl, CHtmlView) void CHtmlCtrl::DoDataExchange(CDataExchange* pDX) { CHtmlView::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CHtmlCtrl, CHtmlView) ON_WM_DESTROY() ON_WM_ERASEBKGND() ON_WM_SIZE() END_MESSAGE_MAP() // CHtmlCtrl 诊断 #ifdef _DEBUG void CHtmlCtrl::AssertValid() const { CHtmlView::AssertValid(); } void CHtmlCtrl::Dump(CDumpContext& dc) const { CHtmlView::Dump(dc); } #endif //_DEBUG // CHtmlCtrl 消息处理程序 BOOL CHtmlCtrl::CreateFromStatic(UINT nID, CWnd* pParent) { CStatic wndStatic; if (!wndStatic.SubclassDlgItem(nID, pParent)) return FALSE; // Get static control rect, convert to parent's client coords. CRect rc; wndStatic.GetWindowRect(&rc); pParent->ScreenToClient(&rc); wndStatic.DestroyWindow(); // create HTML control (CHtmlView) return Create(NULL, // class name NULL, // title (WS_CHILD | WS_VISIBLE ), // style rc, // rectangle pParent, // parent nID, // control ID NULL); // frame/doc context not used } //开始链接时会触发此事件 void CHtmlCtrl::OnBeforeNavigate2(LPCTSTR lpszURL, DWORD /*nFlags*/, LPCTSTR /*lpszTargetFrameName*/, CByteArray& /*baPostedData*/, LPCTSTR /*lpszHeaders*/, BOOL* pbCancel) { *pbCancel = FALSE; if (m_bNewWindow) { *pbCancel = TRUE; CString sUrl = lpszURL; // 处理新建窗口的url if (sUrl.Find(_T("http://www.csdn.net")) != -1) { // 拦截 } else { // 不拦截 ShellExecute 打开新窗口或做其他处理 } } } void CHtmlCtrl::OnDestroy() { // This is probably unnecessary since ~CHtmlView does it, but // safer to mimic CHtmlView::OnDestroy. if (m_pBrowserApp) { m_pBrowserApp = NULL; } CWnd::OnDestroy(); // bypass CView doc/frame stuff } BOOL CHtmlCtrl::OnEraseBkgnd(CDC* /*pDC*/) { return true; } void CHtmlCtrl::OnSize(UINT nType, int cx, int cy) { CFormView::OnSize(nType, cx, cy); //Changed by thilon on 2006.08.10 if (::IsWindow(m_wndBrowser.m_hWnd)) { CRect rect; GetClientRect(rect); // 就这一句与CHtmlView的不同 ::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_EX_CLIENTEDGE); m_wndBrowser.SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER); } } void CHtmlCtrl::PostNcDestroy() { if (m_pHtmlCtrlHandleNewWindow) { delete m_pHtmlCtrlHandleNewWindow; m_pHtmlCtrlHandleNewWindow = NULL; } } void CHtmlCtrl::OnNewWindow2( LPDISPATCH* ppDisp, BOOL* Cancel ) { if (!m_pHtmlCtrlHandleNewWindow) { RECT rc = {0, 0, 100, 200}; m_pHtmlCtrlHandleNewWindow = new CHtmlCtrl(TRUE); m_pHtmlCtrlHandleNewWindow->Create(NULL, // class name NULL, // title (WS_CHILD), // style rc, // rectangle this, // parent 10000, // control ID NULL); } *ppDisp = m_pHtmlCtrlHandleNewWindow->GetApplication(); } CHtmlCtrl::CHtmlCtrl( BOOL bNewWindow /*= FALSE*/ ) { m_bNewWindow = bNewWindow; m_pHtmlCtrlHandleNewWindow = NULL; }
    2009年6月17日 11:29
  • 我晕,代码好难看。不过看起来是抄的C++ Q&A的代码,没什么特别的功能。
    MSMVP VC++
    2009年6月17日 16:16
    版主
  • 真晕啊,,,代码怎么帖成那样子的,,昨天晚上网速慢要回去都没好好看,重贴了你看看?
    还有,论坛怎么没有C++语法显示功能啊
    #pragma once
    
    #include <afxhtml.h>
    
    // CHtmlCtrl Html 视图
    
    class CHtmlCtrl : public CHtmlView
    {
        DECLARE_DYNCREATE(CHtmlCtrl)
    
    public:
        CHtmlCtrl(BOOL bNewWindow = FALSE);;           // 动态创建所使用的受保护的构造函数
        virtual ~CHtmlCtrl(){ };
    
        BOOL CreateFromStatic(UINT nID, CWnd* pParent);
    
    public:
    #ifdef _DEBUG
        virtual void AssertValid() const;
        virtual void Dump(CDumpContext& dc) const;
    #endif
    
        BOOL m_bNewWindow;
    
        CHtmlCtrl * m_pHtmlCtrlHandleNewWindow;
    
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
    
        DECLARE_MESSAGE_MAP()
    public:
        virtual void OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel);
        afx_msg void OnDestroy();
        afx_msg BOOL OnEraseBkgnd(CDC* pDC);
        afx_msg void OnSize(UINT nType, int cx, int cy);
        virtual void OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel);
    protected:
        virtual void PostNcDestroy();
    };
    
    
    
    
    
    C/C++ code
    // HtmlCtrl.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #include "HtmlCtrl.h"
    // CHtmlCtrl
    
    IMPLEMENT_DYNCREATE(CHtmlCtrl, CHtmlView)
    
    
    void CHtmlCtrl::DoDataExchange(CDataExchange* pDX)
    {
        CHtmlView::DoDataExchange(pDX);
    }
    
    BEGIN_MESSAGE_MAP(CHtmlCtrl, CHtmlView)
        ON_WM_DESTROY()
        ON_WM_ERASEBKGND()
        ON_WM_SIZE()
    END_MESSAGE_MAP()
    
    
    // CHtmlCtrl 诊断
    
    #ifdef _DEBUG
    void CHtmlCtrl::AssertValid() const
    {
        CHtmlView::AssertValid();
    }
    
    void CHtmlCtrl::Dump(CDumpContext& dc) const
    {
        CHtmlView::Dump(dc);
    }
    #endif //_DEBUG
    
    
    // CHtmlCtrl 消息处理程序
    BOOL CHtmlCtrl::CreateFromStatic(UINT nID, CWnd* pParent)
    {
        CStatic wndStatic;
        if (!wndStatic.SubclassDlgItem(nID, pParent))
            return FALSE;
    
        // Get static control rect, convert to parent's client coords.
        CRect rc;
        wndStatic.GetWindowRect(&rc);
        pParent->ScreenToClient(&rc);
        wndStatic.DestroyWindow();
    
        // create HTML control (CHtmlView)
        return Create(NULL,                         // class name
            NULL,                                         // title
            (WS_CHILD | WS_VISIBLE ),             // style
            rc,                                         // rectangle
            pParent,                                     // parent
            nID,                                         // control ID
            NULL);                                     // frame/doc context not used
    }
    
    //开始链接时会触发此事件
    void CHtmlCtrl::OnBeforeNavigate2(LPCTSTR lpszURL, DWORD /*nFlags*/, LPCTSTR /*lpszTargetFrameName*/, CByteArray& /*baPostedData*/, LPCTSTR /*lpszHeaders*/, BOOL* pbCancel)
    {
        *pbCancel = FALSE;
    
        if (m_bNewWindow)
        {
            *pbCancel = TRUE;
    
            CString sUrl = lpszURL;
            // 处理新建窗口的url
            if (sUrl.Find(_T("http://www.csdn.net")) != -1)
            {
                // 拦截
            }
            else
            {
                // 不拦截 ShellExecute 打开新窗口或做其他处理
            }
        }
    }
    
    void CHtmlCtrl::OnDestroy()
    {
        // This is probably unnecessary since ~CHtmlView does it, but
        // safer to mimic CHtmlView::OnDestroy.
        if (m_pBrowserApp) 
        {
            m_pBrowserApp = NULL;
        }
        CWnd::OnDestroy(); // bypass CView doc/frame stuff
    }
    
    BOOL CHtmlCtrl::OnEraseBkgnd(CDC* /*pDC*/)
    {
        return true;
    }
    
    void CHtmlCtrl::OnSize(UINT nType, int cx, int cy)
    {
        CFormView::OnSize(nType, cx, cy);            //Changed by thilon on 2006.08.10
    
        if (::IsWindow(m_wndBrowser.m_hWnd)) 
        { 
            CRect rect; 
            GetClientRect(rect); 
            // 就这一句与CHtmlView的不同
            ::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_EX_CLIENTEDGE);
            m_wndBrowser.SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
        } 
    }
    
    void CHtmlCtrl::PostNcDestroy()
    {
        if (m_pHtmlCtrlHandleNewWindow)
        {
            delete m_pHtmlCtrlHandleNewWindow;
            m_pHtmlCtrlHandleNewWindow = NULL;
        }
    }
    
    void CHtmlCtrl::OnNewWindow2( LPDISPATCH* ppDisp, BOOL* Cancel )
    {
        if (!m_pHtmlCtrlHandleNewWindow)
        {
            RECT rc = {0, 0, 100, 200};
    
            m_pHtmlCtrlHandleNewWindow = new CHtmlCtrl(TRUE);
    
            m_pHtmlCtrlHandleNewWindow->Create(NULL,                         // class name
                NULL,                                         // title
                (WS_CHILD),             // style
                rc,                                         // rectangle
                this,                                     // parent
                10000,                                         // control ID
                NULL);
        }
    
        *ppDisp = m_pHtmlCtrlHandleNewWindow->GetApplication();
    }
    
    CHtmlCtrl::CHtmlCtrl( BOOL bNewWindow /*= FALSE*/ )
    {
        m_bNewWindow = bNewWindow;
        m_pHtmlCtrlHandleNewWindow = NULL;
    }
    
    
    
    2009年6月18日 0:34
  • 这个代码看起来就是用m_bNewWindow来判断了,如果是新窗口的话就在BeforeNavigate2里面拦截CSDN的网站,m_bNewWindow在NewWindow2里面设置。
    需要改改加上根据m_bNewWindow的值隐藏窗口和关闭窗口的逻辑。

    Please mark the post answered your question as the answer, and mark other helpful posts as helpful. This posting is provided "AS IS" with no warranties, and confers no rights.
    Visual C++ MVP
    2009年6月21日 16:07
    版主