天天看点

使用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 其他

有兴趣的朋友可以联系我:

欢迎大家发表自己的看法,只要不人身攻击即可,呵呵。

继续阅读