2008年5月30日 星期五

開發 IE 瀏覽器的 Toolbar:開新視窗並做兩視窗間的互動

在研究如何在 toolbar 上,進行另開新視窗,然後還可以兩個 IE 視窗互相溝通,這個問題查了一天半,看了以下幾個屬性或方法:

IHTMLWindow2::open Method
http://msdn.microsoft.com/en-us/library/aa741489(VS.85).aspx
可是得到的都一直是 null!

IHTMLWindow2::opener Property
http://msdn.microsoft.com/en-us/library/aa741490(VS.85).aspx
說只適用於 frame 與 iframe,奇怪,怎麼跟我在 JavaScript 時的經驗不太一樣呢?

IHTMLDocument2::parentWindow Property
http://msdn.microsoft.com/en-us/library/aa752599(VS.85).aspx
認識一下如何從 document 取得 window!

IHTMLDocument2::frames Property
http://msdn.microsoft.com/en-us/library/aa752592(VS.85).aspx
想當然不是這個,因為現在是要處理 window 的互動,不是 frame 的!

IWebBrowser2::Navigate Method
http://msdn.microsoft.com/en-us/library/aa752133(VS.85).aspx
IWebBrowser2::Navigate2 Method
http://msdn.microsoft.com/en-us/library/aa752134(VS.85).aspx
在 C# 的語法中,都得不到回傳值!

最後,只好另外建立一個 InternetExplorer 介面的物件,用它來開啟新視窗,並且在舊視窗中繼續監聽新視窗的事件,這樣一來在視窗處理函式中就仍可存取到舊視窗的物件架構了。

以下是我的 MyToolbar.cs 中的片段程式碼,第三個按鈕的程式:


private InternetExplorer IE;
private DWebBrowserEvents2_DocumentCompleteEventHandler IE_DocumentCompleteEventHandler;

private void button3_Click(object sender, System.EventArgs e)
{
object o = new object();

try
{
IE.Visible = true;
IE.Navigate("http://www.google.com", ref o, ref o, ref o, ref o);
}
catch(Exception exp)
{
IE = new InternetExplorer();
IE.Visible = true;

IE_DocumentCompleteEventHandler = new DWebBrowserEvents2_DocumentCompleteEventHandler(IE_DocumentComplete);
IE.DocumentComplete += IE_DocumentCompleteEventHandler;

IE.Navigate("http://www.google.com", ref o, ref o, ref o, ref o);
}
}

private void IE_DocumentComplete(object pDisp, ref object URL)
{
IWebBrowser2 ie = pDisp as IWebBrowser2;

MessageBox.Show("[Explorer]" + (this.Explorer.Document as HTMLDocumentClass).url
+ "\n[IE]" + (IE.Document as IHTMLDocument2).url
+ "\n[ie]" + (ie.Document as IHTMLDocument2).url);

//IE.DocumentComplete -= IE_DocumentCompleteEventHandler;
}


按下按鈕後,會產生新的視窗,但是新視窗的 DocumentComplete 事件處理程式卻都放在舊視窗中,所以仍可存取到舊視窗的物件,像是在 IE_DocumentComplete() 中的訊息框,Explorer 就代表舊視窗,IE 就代表新視窗,ie 則代表在新視窗中發出事件的來源,因為新視窗的 html 頁面可能會有許多 frame / iframe,所以會發現 ie 會有所不同。

下圖,按下 toolbar 上第三個按鈕,開啟新視窗到 google,並跳出訊息:



下圖,當舊視窗變更網址到 mmug,則當新視窗也變更網址到 yam 時,會看到訊息框中可以正確的得知舊視窗的資訊:



若是,將舊視窗關閉的話,則表示 Listener 已經不存在了,當新視窗在變更網址到其他位置時,將無人監聽事件,所以就不會再有訊息框了,我就不貼沒有訊息框的貼圖了!

借此作法,我們就可以在舊視窗中完全掌控新視窗的事件處理、控制 HTML 物件等等,而且仍可拿到舊視窗的 HTML 物件,得以互動。

沒有留言: