1. 程式人生 > >MFC對話方塊裡利用CHtmlView載入介面(一)————載入網頁

MFC對話方塊裡利用CHtmlView載入介面(一)————載入網頁

首先我們簡單瞭解下CHtmlView類,CHtmlView類是MFC類,它繼承自CView,屬於MFC檢視類。

但我們看它的具體實現時,我們會發現其最大的本質在於IWebBrowser2(WebBrowser ActiveX 控制元件)的封裝。即其實質是:利用IWebBrowser2,有效地使應用程式成為一個 Web 瀏覽器。當然裡面具體的封裝細節,涉及到了大量的COM元件和ActiveX 控制元件知識,我們就不做具體描述。

本文主要介紹:如何利用CHtmlView載入網頁,其具體的建立過程是什麼?

作為例子,我們先VS2015建立一個CHTMLDome1的MFC對話方塊工程。

第一步:新增CBaseHtmlView類

工程建立完成後,在專案解決方案中,新增MFC類,並讓它繼承自CHtmlView類,具體建立過程如下圖。

建立完成後,VS2015會自動為我們生成CBaseHtmlVIew類的.h和.cpp檔案。

這裡有個注意: 在類嚮導中生成的CBaseHtmlView類 其建構函式預設為 protected, 要改成public

第二步:為CBaseHtmlView新增必要的訊息響應函式及虛擬函式

需要重寫的函式有: OnDestroy()、PostNcDestroy()、OnInitialUpdate()、OnMouseActivate()

可以利用類嚮導進行新增,如下圖


上述4個函式分別重寫為:

OnDestroy函式:

void CBaseHtmlView::OnDestroy()
{
	if (m_pBrowserApp) 
	{
		m_pBrowserApp.Release();
		m_pBrowserApp = NULL;
	}
	CWnd::OnDestroy(); //為了跳過CView(doc/frame)的OnDestroy
}

PostNcDestroy函式:

void CBaseHtmlView::PostNcDestroy()
{
	// TODO: Add your specialized code here and/or call the base class
	//CHtmlView::PostNcDestroy();   註釋掉,防止CView 銷燬自己
}
OnInitialUpdate函式:
void CBaseHtmlView::OnInitialUpdate() //用於網頁的載入
{
	CMyHtmlView::OnInitialUpdate();
	Navigate2(L"http://blog.csdn.net/qq_20828983?viewmode=contents", NULL, NULL); //這裡的網站可以任意更換
}
OnMouseActivate函式:
int CBaseHtmlView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
	return CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message); //為了跳過CView(doc/frame)的OnMouseActivate
}

在需要處理網頁大小時,我們還可以過載下OnSize函式:

void CBaseHtmlView::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);

	if (::IsWindow(m_wndBrowser.m_hWnd))
	{
		CRect rect;
		GetClientRect(rect);
		LONG lWindows = GetWindowLong(GetParent()->GetSafeHwnd(), GWL_EXSTYLE);
/*		::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_CLIPSIBLINGS);*/
		::AdjustWindowRectEx(rect, GetStyle(), FALSE, lWindows);
		m_wndBrowser.SetWindowPos(NULL, rect.left, rect.top, 962, 632, SWP_NOACTIVATE | SWP_NOZORDER);
	}
}  

第三步:新增CreateFromStatic建立函式

BOOL CBasesHtmlView::CreateFromStatic(UINT nID, CWnd* pParent)

CreateFromStatic函式兩個引數中 nID為一個CStatic靜態文字框的資源ID,pParent為CStatic靜態文字框所在的對話方塊。

我們傳遞一個CStatic靜態文字框的資源ID,是為了讓此靜態文字框作為載入網頁或HTML的載體。

具體實現如下:

BOOL CBaseHtmlView::CreateFromStatic(UINT nID, CWnd* pParent)
{
	CWnd* pStatic = pParent->GetDlgItem(nID);
	if (pStatic == NULL)
			return FALSE;

	CRect rc;
	pStatic->GetWindowRect(&rc);
	pParent->ScreenToClient(&rc);
	pStatic->DestroyWindow();

	if (!CHtmlView::Create(NULL, NULL, (WS_CHILD | WS_VISIBLE), rc, pParent, nID, NULL))
		return FALSE;

	OnInitialUpdate();  //載入網頁或html
	SetSilent(TRUE);//add by wh ,bid pop script dlg  true表示允許介面彈出對話方塊
	return TRUE;
}
這裡有必要對CHtmlView類中的 Create函式進行下說明:
  virtual BOOL Create(
    LPCTSTR lpszClassName,   //NULL,使用預定義的預設CFrameWnd屬性。
    LPCTSTR lpszWindowName,  //視窗名稱, 可直接為NULL
    DWORD dwStyle,   //視窗風格, 預設情況下, WS_VISIBLE和WS_CHILD設定視窗的樣式
    const RECT& rect,  //指定的大小和視窗的位置 一般用一個static靜態控制元件的位置
    CWnd* pParentWnd,  //指向控制元件的父視窗的指標 
    UINT nID,  //檢視的 ID 號,一般用一個static靜態控制元件ID 
    CCreateContext* pContext = NULL);

第四步:在主對話方塊類中新增CBaseHtmlView成員

在主對話方塊類CHtmlDime1中,新增一個成員變數CBaseHtmlView m_HtmlView。

然後主對話方塊資原始檔中加入一個靜態文字框,屬性修改ID為:IDC_STATIC_HTML

最後在主對話方塊OnInitDialog 中新增:

m_HtmlView.CreateFromStatic(IDC_STATIC_HTML, this);

最後完成,執行結果如下圖:


其他說明

這裡摘取部分:

void GoBack( );   導航到歷史列表的前一個條目(previous item)。

void GoForward( );   導航到歷史列表的下一個條目。

void GoHome( );   導航到主頁,該主頁在IE的屬性中設定。

void GoSearch( );    導航到當前搜尋頁。該頁在IE的屬性中設定。

void Refresh( );      重新裝入瀏覽器當前正在顯示的URL或者檔案,即重新整理。

void Stop( );         撤銷任何未完成的導航或下載,並且停止任何動態的頁面元素,例如背景音樂和動畫。

Navigate        導航到由URL指定的資源。

Navigate2       導航到由URL指定的資源或者由全路徑指定的檔案。

PutProperty     設定與所給定的物件相關的屬性的當前值。

GetProperty     返回與所給定的物件相關的屬性的當前值。

ExecWB         執行一個命令。LoadFromResource  

在WebBrowser控制元件中裝入一個資源。還有一個函式我們重點提及下:OnDocumentCompletevoid

CBaseHtmlView::OnDocumentComplete(LPCTSTR lpszURL)

此函式會在網頁或者html每次載入成功後,進行呼叫。我們可以在裡面處理載入完成後事件,如向主對話方塊傳送訊息,進行通知等。