2008年5月27日 星期二

開發 IE 瀏覽器的 Toolbar:監聽瀏覽器 OnDocumentComplete 事件

繼之前兩篇文章:

開發 IE 瀏覽器的 Toolbar
開發 IE 瀏覽器的 Toolbar:監聽按鈕 onclick 事件

繼續來研究如何監聽瀏覽器讀取網頁完成的事件,因為不管我們要針對網頁內容做什麼處理,前提都是該網頁內容已經完全載入才對。

回到 Extending Explorer with Band Objects using .NET and Windows Forms 中,我們看到 Inside the BandObject 這段中提到:


IObjectWithSite is equired to establish communication with the hosting Explorer process.
Inside the SetSite() method of the BandObject control tries to get a reference to an
IWebBrowser interface - an interface implemented by the top-level object of Explorer.
It will be available through the BandObject.Explorer property.
In the case of a taskbar toolbar there is no IWebBrowser interface so it handles this situation gracefully.
As soon as a pointer to IWebBrowser is retrived, BandObject fires the ExplorerAttached event.
Handling this event is useful when you want to add extra initialization code - subscribing to Web Browser events etc.


所以,只要我們 override 掉 BandObjectLib.cs 的 OnExplorerAttached(),就可以在 toolbar 被載入時自訂監聽 browser 的事件了。因此,我在我的 toolbar 中,增加以下程式碼:


protected override void OnExplorerAttached(EventArgs ea)
{
this.Explorer.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
}

private void OnDocumentComplete(object frame, ref object urlObj)
{
string rooturl = ((this.Explorer as IWebBrowser2).Document as IHTMLDocument2).url;

IWebBrowser2 webBrowser = (IWebBrowser2)frame;
IHTMLDocument2 document = (IHTMLDocument2)webBrowser.Document;

MessageBox.Show("[OnDocumentComplete]\n" + document.title + "\n" + document.url + "\n" + document.url.Equals(rooturl) + "\n" + webBrowser.TopLevelContainer);
}


程式碼中可以看到,this.Explorer 是指最上層瀏覽器,而 frame 則是遇到有切 frame 或使用 iframe 的網站時,各個 frame 的內容也都 "有可能" 觸發 OnDocumentComplete 的時候,在我的訊息中將顯示是否為 root url,當然你也可以直接使用 TopLevelContainer 傳回 bool 值得知。

執行畫面如下,首先,剛開啟 IE 瀏覽器時,我的預設畫面是空白網頁:



接著連到任一個有使用 iframe 的網站,將會看到每個 iframe 的 url 與 title,以及判斷其是否為 TopLevelContainer:



當所有 frame 的訊息框都點掉之後,TopLevelContainer 的 OnDocumentComplete 才會觸發而出現訊息框:



經測試,若是接著按下 F5 或是 Ctrl - R 做 reload 的話,則只有各個 frame 的 OnDocumentComplete 會被再次觸發,TopLevelContainer 的 OnDocumentComplete 則不會被觸發,不過其實各個 frame 的 OnDocumentComplete 也不見得每次都會被觸發。

沒有留言: