天天看點

使用Vs2005打造簡單分頁浏覽器(1)原創

                                             使用Vs2005打造簡單分頁浏覽器(1)原創

1引言<b></b>

2功能

3實作過程以及關鍵點

4總結

5不足之處

6其他

7 代碼下載下傳 

1    引言

很早就有搞一個浏覽器的想法了,在vs2003上就試圖做過,苦于經常會有這種情況出現:當自治的浏覽器遇到彈出視窗時無法捕獲新的彈出視窗,于是乎新的彈出視窗仍舊用ie(或其他系統預設浏覽器)打開,在研究vs2005的WebBrowser控件時發現有NewWindow事件,于是乎興奮不已,決定用這個分頁浏覽器體驗一下vs2005.

不過就在寫這篇blog時突然想到在vs2003的那個axWebBrowse元件是否有這個事件呢?原來也有!隻是封裝的沒有vs2005的好,也不知道怎麼會有兩個此類的事件。是以在2003下應該也可以實作分頁(後續的文章會有介紹)。

2   實作功能

預覽圖如下:

2.1

目前浏覽器的"另存為","列印","列印禦覽","頁面設定",重新整理,前進,後退等等。幾乎都是控件封裝好了的,沒有幾句代碼。

2.2 浏覽器的分頁功能。當浏覽器有NewWindow激發時産生新的一頁。主要依靠NewWindow事件。

2.3目前頁面的狀态。例如标題,狀态欄等。

3 實作過程以及關鍵點

建立一個vs2005的windows applaction項目

3.1界面

一個MenuStrip實作最上面的菜單。

兩個ToolStrip分别是工具欄和位址欄。

一個TabControl也就是浏覽器的主體了,它的每個TabPage就是每一個分頁了。

一個StatusStrip也就是狀态欄了。

另外為了使窗體大小變化時控件也随着變化注意使用控件的dock屬性。

搭成如下界面:

順便說一句和vs2003不同的是vs2005把例如

            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();

            this.saveasToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();

            this.printToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.printPreToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();

            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

這些通過我們拖拽控件,系統生成的界面代碼分離出來統一放在叫*.Designer.cs檔案裡了,詳見事例代碼中的Form1.Designer.cs檔案。

3.2    具體code

&lt;?xml:namespace prefix="st1"?&gt;3.2.1 輔助方法

#region //輔助方法

        /// &lt;summary&gt;

        /// 當在浏覽器位址欄敲"回車"時目前浏覽器重定向到指定url(tscbUrl.Tex)

        /// &lt;/summary&gt;

        /// &lt;param name="sender"&gt;&lt;/param&gt;

        /// &lt;param name="e"&gt;&lt;/param&gt;

        private void tscbUrl_KeyDown(object sender, KeyEventArgs e)

        {

            if (e.KeyCode == Keys.Enter)

            {

                newCurrentPageUrl(tscbUrl.Text);

            }

        }

        /// 建立空白頁

        private void newPage()

            tscbUrl.Text = "about:blank";

            TabPage mypage = new TabPage();

            WebBrowser tempBrowser = new WebBrowser();

            tempBrowser.Navigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);

            tempBrowser.NewWindow += new CancelEventHandler(tempBrowser_NewWindow);

            tempBrowser.ProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);

            tempBrowser.StatusTextChanged += new EventHandler(tempBrowser_StatusTextChanged);

            tempBrowser.Dock = DockStyle.Fill;

            mypage.Controls.Add(tempBrowser);

            tabControl1.TabPages.Add(mypage);

            tabControl1.SelectedTab = mypage;

        /// 臨時浏覽器進度變化事件

        void tempBrowser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)

            toolStripProgressBar1.Maximum = (int)e.MaximumProgress;

            toolStripProgressBar1.Value = (int)e.CurrentProgress;

        /// 建立一頁并定向到指定url

        /// &lt;param name="address"&gt;新一頁的浏覽器重新定向到的url&lt;/param&gt;

        private void newPage(string address)

            tempBrowser.Url = getUrl(address);

        /// 擷取目前浏覽器

        /// &lt;returns&gt;目前浏覽器&lt;/returns&gt;

        private WebBrowser getCurrentBrowser()

            WebBrowser currentBrowser = (WebBrowser)tabControl1.SelectedTab.Controls[0];

            return currentBrowser;

        }  

        /// 處理字元串為合法url

        /// &lt;param name="address"&gt;&lt;/param&gt;

        /// &lt;returns&gt;&lt;/returns&gt;

        private Uri getUrl(string address)

            string tempaddress = address;

            if ((!address.StartsWith("http://")) &amp;&amp; (!address.StartsWith("https://")) &amp;&amp; (!address.StartsWith("ftp://")))

                tempaddress = "http://" + address;

            Uri myurl;

            try

                myurl = new Uri(tempaddress);

            catch

                 myurl = new Uri("about:blank");

            return myurl;

        /// 截取字元串為指定長度

        /// &lt;param name="oldstring"&gt;&lt;/param&gt;

        private string newstring(string oldstring)

            string temp;

            if (oldstring.Length &lt; TITLE_COUNT)

                temp = oldstring;

            else

                temp = oldstring.Substring(0, TITLE_COUNT);

            return temp;

        /// 設定"前進","後退"button的可用狀态

        private void setStatusButton()

            backButton.Enabled = getCurrentBrowser().CanGoBack;

            forwordButton.Enabled = getCurrentBrowser().CanGoForward;

        #endregion

說明:其中getCurrentBrowser()是擷取目前頁面的浏覽器,這裡把它叫目前浏覽器,即getCurrentBrowser()為擷取目前浏覽器。

3.2.22<b></b>

菜單欄

#region//菜單欄

        /// 另存為

        private void saveasToolStripMenuItem_Click(object sender, EventArgs e)

            getCurrentBrowser().ShowSaveAsDialog();

        /// 列印

        private void printToolStripMenuItem_Click(object sender, EventArgs e)

            getCurrentBrowser().ShowPrintDialog();

        /// 列印禦覽

        private void printPreToolStripMenuItem_Click(object sender, EventArgs e)

            getCurrentBrowser().ShowPrintPreviewDialog();

        /// 關閉浏覽器

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)

            Application.Exit();

        /// 頁面設定

        private void pageSetupToolStripMenuItem_Click(object sender, EventArgs e)

            getCurrentBrowser().ShowPageSetupDialog();

        /// 屬性設定

        private void propeToolStripMenuItem_Click(object sender, EventArgs e)

            getCurrentBrowser().ShowPropertiesDialog();

        #region//關于

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)

            AboutBox1 myabout = new AboutBox1();

            myabout.Show();

        private void tipToolStripMenuItem_Click(object sender, EventArgs e)

            MessageBox.Show("小提示:輕按兩下分頁标題即可關閉目前頁面。");

說明:其中檔案菜單的功能大都是WebBrowser控件封裝好的僅僅是用上文提到的getCurrentBrowser()擷取一下目前浏覽器罷了。

3.2.3工具欄

 #region//工具欄

        /// 後退

        private void backButton_Click(object sender, EventArgs e)

            getCurrentBrowser().GoBack();

            setStatusButton();

        /// 前進

        private void forwordButton_Click(object sender, EventArgs e)

            getCurrentBrowser().GoForward();

        /// 停止

        private void stopButton_Click(object sender, EventArgs e)

            getCurrentBrowser().Stop();

        /// 重新整理

        private void refreshButton_Click(object sender, EventArgs e)

            getCurrentBrowser().Refresh();

        /// 定向到首頁

        private void homeButton_Click(object sender, EventArgs e)

            getCurrentBrowser().GoHome();

        /// 搜尋

        private void searchButton_Click(object sender, EventArgs e)

            getCurrentBrowser().GoSearch();

        private void printButton_Click(object sender, EventArgs e)

            getCurrentBrowser().Print();

        private void newButton_Click(object sender, EventArgs e)

            newPage();

        /// 使目前的浏覽器定位到給定url

        private void gotoButton_Click(object sender, EventArgs e)

            newCurrentPageUrl(tscbUrl.Text);

說明:和菜單欄實作的功能類似,也是一些簡單的調用,僅僅是表現形式不同。

3.2.4 初始化

#region//初始化

        /// 初始化

        private void Form1_Load(object sender, EventArgs e)

            initMainForm();

        /// 初始化浏覽器

        private void initMainForm()

            tempBrowser.GoHome();//和建立空白頁不同

說明:分頁浏覽器初始化時要定向到首頁,雖然我們的浏覽器暫時沒有提供設定首頁的功能。

3.2.5臨時浏覽器事件

#region//臨時浏覽器事件

        /// 臨時浏覽器狀态變化事件

        void tempBrowser_StatusTextChanged(object sender, EventArgs e)

            WebBrowser myBrowser = (WebBrowser)sender;

            if (myBrowser != getCurrentBrowser())

                return;

                toolStripStatusLabel1.Text = myBrowser.StatusText;

        }    

      /// 在目前頁面上重新定向

      /// &lt;/summary&gt;

      /// &lt;param name="address"&gt;url&lt;/param&gt;

        private void newCurrentPageUrl(String address)

            getCurrentBrowser().Navigate(getUrl(address));

       /// &lt;summary&gt;

        /// 臨時浏覽器産生新窗體事件

        void tempBrowser_NewWindow(object sender, CancelEventArgs e)

            //擷取觸發tempBrowser_NewWindow事件的浏覽器

            //擷取觸發tempBrowser_NewWindow事件的浏覽器所在TabPage

            TabPage mypage = (TabPage)myBrowser.Parent;

            //通過StatusText屬性獲得新的url

            string NewURL = ((WebBrowser)sender).StatusText;

            //生成新的一頁

            TabPage TabPageTemp = new TabPage();

            //生成新的tempBrowser

            //臨時浏覽器定向到新的url

            tempBrowser.Navigate(NewURL);

            //為臨時浏覽器關聯NewWindow等事件

            tempBrowser.StatusTextChanged+=new EventHandler(tempBrowser_StatusTextChanged);

            //将臨時浏覽器添加到臨時TabPage中

            TabPageTemp.Controls.Add(tempBrowser);

            //将臨時TabPage添加到主窗體中

            this.tabControl1.TabPages.Add(TabPageTemp);

            //使外部無法捕獲此事件

            e.Cancel = true;

        /// 臨時浏覽器定向完畢

        private void tempBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e)

            tscbUrl.Text = getCurrentBrowser().Url.ToString();

            WebBrowser mybrowser = (WebBrowser)sender;

            TabPage mypage=(TabPage)mybrowser.Parent;

            //設定臨時浏覽器所在tab标題

            mypage.Text= newstring(mybrowser.DocumentTitle);

      說明:臨時浏覽器實際上是用程式的方式先new出一個tempBrowser然後添加到一個分頁中去。其中這個tempBrowser我稱它為臨時浏覽器。其中

void tempBrowser_NewWindow(object sender, CancelEventArgs e){..}

事件是比較重要的,我認為它是整個程式的核心部分。

3.2.6 tabControl1事件<b></b>

  #region//tabControl1事件

        /// 切換tab

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)

            WebBrowser mybor = (WebBrowser)tabControl1.SelectedTab.Controls[0];

            if (mybor.Url != null)

                //位址輸入框

                tscbUrl.Text = mybor.Url.ToString();

                tabControl1.SelectedTab.Text = newstring(mybor.DocumentTitle);

                tscbUrl.Text = "about:blank";

                tabControl1.SelectedTab.Text = "空白頁";

        /// 關閉目前tab

        private void tabControl1_DoubleClick(object sender, EventArgs e)

            //僅僅剩下一個tab時傳回

            if (tabControl1.TabPages.Count &lt;= 1)

                getCurrentBrowser().Navigate("about:blank");

                //先将tabControl1隐藏然後remove掉目标tab(如果不隐藏則出現閃爍,即系統自動調轉到tabControl1的第一個tab然後跳會。)最後顯示tabControl1。

                tabControl1.Visible = false;

                WebBrowser mybor = getCurrentBrowser();

                //釋放資源

                mybor.Dispose();

                mybor.Controls.Clear();

                this.tabControl1.TabPages.Remove(this.tabControl1.SelectedTab);

                //重新設定目前tab

                tabControl1.SelectedTab = tabControl1.TabPages[tabControl1.TabPages.Count - 1];

說明:當輕按兩下目前Tabpage進而關閉目前頁面時,tabControl1 會首先定位到第一個tab然後再定位到指定的Tabpage上,我采取隐藏tabControl1-處理-顯示tabControl1思路解決此問題。

4 總結

分頁浏覽器所謂"分頁",從實作上講就是"控件的動态添加",目前浏覽器産生新窗體時,先new出一個TabPage,再new一個WebBrowser,把這個WebBrowser加載了一些事件以後添加到先前的這個TabPage上,然後把這個TabPage添加到"主窗體"tabControl1中。

5 不足之處

最大的不足:

用((WebBrowser)sender).StatusText無法捕獲的url(例如StatusText 為"javascript:void(0)")目前無法解決這也是某些莫名其妙的問題的出處。

另外某些腳本不支援。

其他一些罪狀讓我們共同羅列…

6 其他

有興趣的朋友可以聯系我:

歡迎大家發表自己的看法,隻要不人身攻擊即可,呵呵。

繼續閱讀