1. 程式人生 > >【MFC】在CHtmlView中在同一窗口顯示新打開頁面

【MFC】在CHtmlView中在同一窗口顯示新打開頁面

是個 頁面 window nav html 返回 str turn ESS

使用MFC的單文檔,用IE核心做的簡單瀏覽器。當打開一個新的鏈接時,IE核心會使用IE來打開一個新窗口顯示打開的新頁面。為了讓新頁面在本程序中顯示,我試了如下方法,其中的問題一並列出:

方法1、重載CHTMLView::OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel);

註意:在90%的情況下,這是個非常好用的方法。比較特殊的地方是2345.com這個網站中,當鼠標指向比如“百度”、“騰訊”等鏈接時,會自動生成一個下拉列表。如果點擊這些產生的下拉列表中的項,這種方法就失效了。依然會使用IE打開。

這是我遇到的情況。原因是lpElem->getAttribute(TEXT("href"), 0, &url)成功了,但是返回的URL是空的。

具體的實現內容參考:https://blog.csdn.net/xiangzhang321/article/details/7753177

void CXxxxView::OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel)
{
    CComPtr<IHTMLDocument2> lpDoc2;
    CHtmlView::m_pBrowserApp->get_Document((IDispatch**)&lpDoc2);
    if ( lpDoc2 == NULL )
        return;
    
    CComPtr
<IHTMLElement> lpElem; lpDoc2->get_activeElement(&lpElem); if ( lpElem == NULL ) return; variant_t url; HRESULT hr = lpElem->getAttribute(L"href", 0, &url); if ( SUCCEEDED(hr) && url.vt != VT_NULL ) { hr = m_pBrowserApp->Navigate2(&url, NULL, NULL, NULL, NULL);
if ( SUCCEEDED(hr) ) *Cancel = TRUE; url.Clear(); } }

方法2、添加CHTMLView::NewWindow3(IDispatch **ppDisp, VARIANT_BOOL *Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl);

註意:網上在NewWindow3有其他實現,具體的可以參考:https://www.cnblogs.com/macher/p/4495234.html。他的實現在我這裏雖然不使用IE打開新窗口,但是本程序也無法打開新窗口。在下面的實現代碼中,不要使用SendMessage發送自定義消息。

使用了SendMessage發送消息的結果是跟我前面提到的結果一樣。

步驟:1、在CXxxxView中添加DECLARE_EVENTSINK_MAP()

2、在CPP中添加:

BEGIN_EVENTSINK_MAP(CXxxxView, CHtmlView)
    ON_EVENT(CXxxxView, AFX_IDW_PANE_FIRST, 273, CXxxxView::NewWindow3, VTS_PDISPATCH VTS_PBOOL VTS_I4 VTS_BSTR VTS_BSTR)
END_EVENTSINK_MAP()

3、NewWindow3的實現:

void CXxxxView::NewWindow3(IDispatch **ppDisp, VARIANT_BOOL *Cancel, DWORD dwFlags, BSTR bstrUrlContext, BSTR bstrUrl)
{
    *Cancel = TRUE;
    this->GetMainFrame()->PostMessage(WM_XXXX_NEWPAGE, (WPARAM)((LPCTSTR)bstrUrl));
}

【MFC】在CHtmlView中在同一窗口顯示新打開頁面