IE裡的探索之定製瀏覽器好助手(下) (轉)

amyz發表於2007-11-25
IE裡的探索之定製瀏覽器好助手(下) (轉)[@more@]

.com/tech//2001/02/08/58_1642.html">出處:

IE裡的探索之定製好助手(下)
(作者:青蘋果工作室編譯 2001年02月08日 14:00)

訪問文件
  現在 BHO 引用了 Internet Explorer 的 WebBrowser 並已經連線到瀏覽器 以接收它產生的事件。在 Web 頁面被完全並被正確地初始化之後,現在終於可以透過 文件物件模型訪問它了。WebBrowser 的 Document 屬性返回一個指向文件物件的 IDispatch 介面的指標:

  CComPtr pDisp;

  HRESULT hr = m_spWebBrowser2->get_Document(&pDisp);

  get_Document() 方法提供的只是一個指向介面的指標。我們需要確定在 IDispatch 指標後面確實是一個 HTML 文件物件。如果使用 ,以下是等價的程式碼:

  Dim doc As

  Set doc = WebBrowser1.Document

  If TypeName(doc)="HTMLDocument" Then

   ' Get the document content and display

  Else

   ' Disable the display dialog

  End If

  現在我們需要判斷 get_Document() 返回的 IDispatch 指標的實質。Internet Explorer 不僅是一個 HTML 瀏覽器,還能處理任何 文件 ;即任何有作為 ActiveX 文件服務的應用程式支援的文件。這樣一來,就不能保證檢視的文件的確是一個 HTML 頁面。

  有一個解決辦法就是檢視 URL 並檢查 URL 的副檔名。但該如何處理 Active Server Pages () 或一個暗含指向 HTML 頁面的 URL?如果你使用了像 about 或 res 這樣的定製又該如何?

  我們決定採取另一種方式,它和上面的 Visual Basic 程式碼性質相同。這種想法就是,如果 IDispatch 指標確實指向一個 HTML 文件,對 IHTMLDocument2 介面的訪問就能成功地返回。IHTMLDocument2 是綜合了 DHTML 物件模型為 HTML 頁面實現的所用功能的介面。以下程式碼片斷說明如何進行這樣的判斷:

  CComPtr pDisp;

  HRESULT hr = m_spWebBrowser2->get_Document(&pDisp);

  CComQIPtr spHTML;

  spHTML = pDisp;

  if (spHTML) {

   // 取得文件的內容並顯示它

  }

  else {

   // 禁止程式碼視窗控制元件

  }

  如果訪問 IHTMLDocument2 介面失敗,spHTML 指標為 NULL。否則,我們就可以正常訪問 DHTML 物件模型的方法和屬性了。

  現在的問題是如何獲得已顯示的頁面的。幸好,基本的 DHTML 知識就足以做到這一點。由於 HTML 頁面將它所有的內容包含在 標記中,DHTML 物件模型要求你首先獲得指向 Body 物件的指標:

  CComPtr m_pBody;

  hr = spHTML->get_body(&m_pBody);

  奇特的是,DHTML 物件模型不讓你知道在 之前的標記,例如 的原始內容。這些內容已經被處理並被儲存到一系列屬性中了,但你依然不能得到一個最初的 HTML 的原始內容。然而,現在 body 能告訴我們的就足夠了。我們需要將 outerHTML 屬性的內容讀取到一個 BSTR 變數裡以獲得包含在 和 之間的 HTML 程式碼。

  BSTR bstrHTMLText;

  hr = m_pBody->get_outerHTML(&bstrHTMLText);

  現在,在程式碼視窗中顯示文字的工作就是建立視窗、將字串從 Unicode 轉換為 ANSI,並如圖 3 中所示設定編輯框。以下是完成這些工作的全部程式碼:

  HRESULT CView::GetDocumentContent()

  {

   USES_CONVERSION;

  

   // 獲得 WebBrowser 文件物件

   CComPtr pDisp;

   HRESULT hr = m_spWebBrowser2->get_Document(&pDisp);

   if (FAILED(hr))

   return hr;

   // 驗證我們得到了一個指向 IHTMLDocument2 介面的指標

   // 我們查詢 IHTMLDocument2 介面 (透過靈巧指標)

   CComQIPtr spHTML;

   spHTML = pDisp;

   // 獲得文件的原始碼

   if (spHTML)

   {

   // 獲得 BODY 物件

   hr = spHTML->get_body(&m_pBody);

   if (FAILED(hr))

       return hr;

   // 獲得 HTML 文字

   BSTR bstrHTMLText;

   hr = m_pBody->get_outerHTML(&bstrHTMLText);

   if (FAILED(hr))

   return hr;

   // 將文字從 Unicode 轉換為 ANSI

   LPTSTR psz = new TCHAR[SysStringLen(bstrHTMLText)];

   lstrcpy(psz, OLE2T(bstrHTMLText));

   // 允許修改文字

   HWND hwnd = m_dlgCode.GetDlgItem(IDC_TEXT);

   EnableWindow(hwnd, true);

   hwnd = m_dlgCode.GetDlgItem(IDC_APPLY);

   EnableWindow(hwnd, true);

   // 設定程式碼視窗的文字

   m_dlgCode.SetDlgItemText(IDC_TEXT, psz);

   delete [] psz;

   }

   else // 文件不是 HTML 頁面

   {

   m_dlgCode.SetDlgItemText(IDC_TEXT, "");

   HWND hwnd = m_dlgCode.GetDlgItem(IDC_TEXT);

   EnableWindow(hwnd, false);

   hwnd = m_dlgCode.GetDlgItem(IDC_APPLY);

   EnableWindow(hwnd, false);

   }

   return S_OK;

  }

  由於我們執行這段程式碼以響應 DocumentComplete 通知,每個新頁面都會迅速地自動處理。DHTML 物件模型允許你修改顯現的頁面的結構,但在你按 F5 鍵或瀏覽器的 Refresh 按鈕重新整理檢視後,所有的修改會立即丟失。透過對 Complete 事件進行處理你能同時重新整理程式碼視窗。(注意 DownloadComplete 事件比 DocumentComplete 事件先到達) 這時,你應該忽略第一次下載頁面時產生的 DownloadComplete 而只考慮重新整理時產生的事件。一個簡單的布林成員例如 m_bDocumentCompleted 可以用來區分這兩種情況。

管理程式碼視窗
  用以顯示當前頁面的 HTML 原始碼的程式碼視窗是 ATL 的另一個基本元素,一個可以在 ATL 物件嚮導的 Miscellaneous 頁裡找到的對話方塊視窗。我們重置這個視窗的尺寸以響應 WM_INITDIALOG 訊息,並使此視窗占據桌面工作區,即螢幕的可用部分減掉工作列可能佔據位置最下面的部分。

  瀏覽器啟動時此視窗可能出現也可能不出現。預設情況下它是出現的,但可以透過清除核取方塊 Show window at startup 禁止。如果你願意也可以關掉它。隨後,可以在任何時候按 F12 鍵將其召回。F12 由我們在 SetSite() 中的鍵盤掛鉤捕獲。

  啟動設定完全按照 指示儲存在登錄檔裡。讀寫登錄檔時我們沒有使用 ,而是使用了新的 Lightweight (shli.dll),這樣 可以避免開啟和關閉相應的登錄檔項的麻煩:

  D dwType, dwVal;

  DWORD dwSize = sizeof(DWORD);

  SHGetValue(HKEY_CURRENT_USER, _T("SoftwareMSDNBHO"),

   _T("ShowWindowAtStartup"), &dwType, &dwVal, &dwSize);

  這個 DLL 是在 Internet Explorer 4.0 和 Active Desktop 中引入的,從 98 開始成為標準的。這些函式比相應的 Win32 函式更直接,適合只進行一次讀寫時使用。

註冊助手物件
  BHO 是 服務程式,應該同時以 COM 服務程式和 BHO 註冊。ATL 模板為你提供了完成第一項註冊的註冊指令碼程式碼 (RGS) 。以下是完成 BHO 註冊的 RGS 程式碼。(CLSID 是從例程式中得到的。)

  HKLM {

   SOFTWARE {

   Microsoft {

   Windows {

   CurrentVersion {

     Explorer {

      'Browser Helper Objects' {

      ForceRemove {1E1B2879-88FF-11D2-8D96-D7ACAC95951F}

  }}}}}}}

  注意 ForceRemove 子句使鍵在物件取消註冊時被刪除。

  在 Browser Helper Objects 鍵下是所有安裝的助手物件。瀏覽器從不將這些放入快取,所以安裝並測試 BHO 是一個很快的過程。

BHO小結
  本文中,我們介紹了瀏覽器助手物件,一種相對來說比較新的、在瀏覽器的地址空間內直接引入你的程式碼的有效方式。你所要做的就是編寫一個 COM 服務程式以支援 IObjectWithSite 介面。這裡,你的模組從所有預定目的來看都是瀏覽器機構中的一個元件。本文中我們建立的例程式還涉及到如 COM 事件、動態 HTML 物件模型以及 WebBrowser 介面等內容。我們認為它演示了 BHO 的功能,同時提供了一個建立你自己物件的實用平臺。如果你需要知道瀏覽器正在顯示什麼,你一定需要熟悉事件並進一步瞭解 WebBrowser。現在你知道:預先警告是為了早做準備。作為結語,我們提醒你 BHO 對 Windows Explorer 非常有用,而且,透過 WebBrowser,它能由你的程式碼。


 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-984576/,如需轉載,請註明出處,否則將追究法律責任。

相關文章