VS2005打造简单分页浏览器

  • 来源: 龙腾软件教程网 作者: 若水   2008-05-09/06:58
  •  很早就有搞一个浏览器的想法了,在vs2003上就试图做过,苦于经常会有这种情况出现:当自治的浏览器遇到弹出窗口时无法捕获新的弹出窗口,于是乎新的弹出窗口仍旧用ie(或其他系统默认浏览器)打开,在研究vs2005的WebBrowser控件时发现有NewWindow事件,于是乎兴奋不已,决定用这个分页浏览器体验一下vs2005。

    实现功能

    预览图如下:



    当前浏览器的"另存为","打印","打印御览","页面设置",刷新,前进,后退等等。几乎都是控件封装好了的,没有几句代码。

    浏览器的分页功能。当浏览器有NewWindow激发时产生新的一页。主要依靠NewWindow事件。

    当前页面的状态。例如标题,状态栏等。

    实现过程以及关键点

    新建一个vs2005的windows applaction项目

    界面

    一个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文件。


    辅助方法

    #region //辅助方法
    /// <summary>
    /// 当在浏览器地址栏敲"回车"时当前浏览器重定向到指定url(tscbUrl.Tex)
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void tscbUrl_KeyDown(object sender, KeyEventArgs e)
    {
    if (e.KeyCode == Keys.Enter)
    {
    newCurrentPageUrl(tscbUrl.Text);
    }
    }
    /// <summary>
    /// 新建空白页
    /// </summary>
    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;
    }
    /// <summary>
    /// 临时浏览器进度变化事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void tempBrowser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
    {
    toolStripProgressBar1.Maximum = (int)e.MaximumProgress;
    toolStripProgressBar1.Value = (int)e.CurrentProgress;
    }
    /// <summary>
    /// 新建一页并定向到指定url
    /// </summary>
    /// <param name="address">新一页的浏览器重新定向到的url</param>
    private void newPage(string address)
    {
    TabPage mypage = new TabPage();
    WebBrowser tempBrowser = new WebBrowser();
    tempBrowser.Navigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
    tempBrowser.NewWindow += new CancelEventHandler(tempBrowser_NewWindow);
    tempBrowser.StatusTextChanged += new EventHandler(tempBrowser_StatusTextChanged);
    tempBrowser.ProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
    tempBrowser.Url = getUrl(address);
    tempBrowser.Dock = DockStyle.Fill;
    mypage.Controls.Add(tempBrowser);
    tabControl1.TabPages.Add(mypage);
    }
    /// <summary>
    /// 获取当前浏览器
    /// </summary>
    /// <returns>当前浏览器</returns>
    private WebBrowser getCurrentBrowser()
    {
    WebBrowser currentBrowser = (WebBrowser)tabControl1.SelectedTab.Controls[0];
    return currentBrowser;
    }
    /// <summary>
    /// 处理字符串为合法url
    /// </summary>
    /// <param name="address"></param>
    /// <returns></returns>
    private Uri getUrl(string address)
    {
    string tempaddress = address;
    if ((!address.StartsWith("http://")) && (!address.StartsWith("https://")) && (!address.StartsWith("ftp://")))
    {
    tempaddress = "http://" + address;
    }
    Uri myurl;
    try
    {
    myurl = new Uri(tempaddress);
    }
    catch
    {
    myurl = new Uri("about:blank");
    }
    return myurl;
    }
    /// <summary>
    /// 截取字符串为指定长度
    /// </summary>
    /// <param name="oldstring"></param>
    /// <returns></returns>
    private string newstring(string oldstring)
    {
    string temp;
    if (oldstring.Length < TITLE_COUNT)
    {
    temp = oldstring;
    }
    else
    {
    temp = oldstring.Substring(0, TITLE_COUNT);
    }
    return temp;
    }
    /// <summary>
    /// 设置"前进","后退"button的可用状态
    /// </summary>
    private void setStatusButton()
    {
    backButton.Enabled = getCurrentBrowser().CanGoBack;
    forwordButton.Enabled = getCurrentBrowser().CanGoForward;
    }
    #endregion
    #p#分页标题#e#


    说明:其中getCurrentBrowser()是获取当前页面的浏览器,这里把它叫当前浏览器,即getCurrentBrowser()为获取当前浏览器。


    菜单栏

    #region//菜单栏
    /// <summary>
    /// 另存为
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void saveasToolStripMenuItem_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().ShowSaveAsDialog();
    }
    /// <summary>
    /// 打印
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void printToolStripMenuItem_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().ShowPrintDialog();
    }
    /// <summary>
    /// 打印御览
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void printPreToolStripMenuItem_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().ShowPrintPreviewDialog();
    }
    /// <summary>
    /// 关闭浏览器
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
    Application.Exit();
    }
    /// <summary>
    /// 页面设置
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void pageSetupToolStripMenuItem_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().ShowPageSetupDialog();
    }
    /// <summary>
    /// 属性设置
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    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("小提示:双击分页标题即可关闭当前页面。");
    }
    #endregion
    #endregion

    说明:其中文件菜单的功能大都是WebBrowser控件封装好的仅仅是用上文提到的getCurrentBrowser()获取一下当前浏览器罢了。

    工具栏

    #region//工具栏
    /// <summary>
    /// 后退
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void backButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().GoBack();
    setStatusButton();
    }
    /// <summary>
    /// 前进
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void forwordButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().GoForward();
    setStatusButton();
    }
    /// <summary>
    /// 停止
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void stopButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().Stop();
    }
    /// <summary>
    /// 刷新
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void refreshButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().Refresh();
    }
    /// <summary>
    /// 定向到主页
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void homeButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().GoHome();
    }
    /// <summary>
    /// 搜索
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void searchButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().GoSearch();
    }
    /// <summary>
    /// 打印
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void printButton_Click(object sender, EventArgs e)
    {
    getCurrentBrowser().Print();
    }
    /// <summary>
    /// 新建空白页
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void newButton_Click(object sender, EventArgs e)
    {
    newPage();
    }
    /// <summary>
    /// 使当前的浏览器定位到给定url
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void gotoButton_Click(object sender, EventArgs e)
    {
    newCurrentPageUrl(tscbUrl.Text);
    }
    #endregion
    #p#分页标题#e#


    说明:和菜单栏实现的功能类似,也是一些简单的调用,仅仅是表现形式不同。

    初始化

    #region//初始化
    /// <summary>
    /// 初始化
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Form1_Load(object sender, EventArgs e)
    {
    initMainForm();
    }
    /// <summary>
    /// 初始化浏览器
    /// </summary>
    private void initMainForm()
    {
    TabPage mypage = new TabPage();
    WebBrowser tempBrowser = new WebBrowser();
    tempBrowser.Navigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
    tempBrowser.NewWindow += new CancelEventHandler(tempBrowser_NewWindow);
    tempBrowser.StatusTextChanged += new EventHandler(tempBrowser_StatusTextChanged);
    tempBrowser.ProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
    tempBrowser.Dock = DockStyle.Fill;
    tempBrowser.GoHome();//和新建空白页不同
    mypage.Controls.Add(tempBrowser);
    tabControl1.TabPages.Add(mypage);
    }

    #endregion

    说明:分页浏览器初始化时要定向到主页,虽然我们的浏览器暂时没有提供设置主页的功能。

    临时浏览器事件

    #region//临时浏览器事件
    /// <summary>
    /// 临时浏览器状态变化事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void tempBrowser_StatusTextChanged(object sender, EventArgs e)
    {
    WebBrowser myBrowser = (WebBrowser)sender;
    if (myBrowser != getCurrentBrowser())
    {
    return;
    }
    else
    {
    toolStripStatusLabel1.Text = myBrowser.StatusText;
    }
    }
    /// <summary>
    /// 在当前页面上重新定向
    /// </summary>
    /// <param name="address">url</param>
    private void newCurrentPageUrl(String address)
    {
    getCurrentBrowser().Navigate(getUrl(address));
    }
    /// <summary>
    /// 临时浏览器产生新窗体事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void tempBrowser_NewWindow(object sender, CancelEventArgs e)
    {
    //获取触发tempBrowser_NewWindow事件的浏览器
    WebBrowser myBrowser = (WebBrowser)sender;
    //获取触发tempBrowser_NewWindow事件的浏览器所在TabPage
    TabPage mypage = (TabPage)myBrowser.Parent;
    //通过StatusText属性获得新的url
    string NewURL = ((WebBrowser)sender).StatusText;
    //生成新的一页
    TabPage TabPageTemp = new TabPage();
    //生成新的tempBrowser
    WebBrowser tempBrowser = new WebBrowser();
    //临时浏览器定向到新的url
    tempBrowser.Navigate(NewURL);
    tempBrowser.Dock = DockStyle.Fill;
    //为临时浏览器关联NewWindow等事件
    tempBrowser.NewWindow += new CancelEventHandler(tempBrowser_NewWindow);
    tempBrowser.Navigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
    tempBrowser.ProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
    tempBrowser.StatusTextChanged+=new EventHandler(tempBrowser_StatusTextChanged);
    //将临时浏览器添加到临时TabPage中
    TabPageTemp.Controls.Add(tempBrowser);
    //将临时TabPage添加到主窗体中
    this.tabControl1.TabPages.Add(TabPageTemp);
    //使外部无法捕获此事件
    e.Cancel = true;
    }
    /// <summary>
    /// 临时浏览器定向完毕
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    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);
    }
    #endregion

    说明:临时浏览器实际上是用程序的方式先new出一个tempBrowser然后添加到一个分页中去。其中这个tempBrowser我称它为临时浏览器。其中void tempBrowser_NewWindow(object sender, CancelEventArgs e){..}事件是比较重要的,我认为它是整个程序的核心部分。

    tabControl1事件

    #region//tabControl1事件
    /// <summary>
    /// 切换tab
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    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);
    }
    else
    {
    tscbUrl.Text = "about:blank";
    tabControl1.SelectedTab.Text = "空白页";
    }
    setStatusButton();
    }
    /// <summary>
    /// 关闭当前tab
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void tabControl1_DoubleClick(object sender, EventArgs e)
    {
    //仅仅剩下一个tab时返回
    if (tabControl1.TabPages.Count <= 1)
    {
    tabControl1.SelectedTab.Text = "空白页";
    getCurrentBrowser().Navigate("about:blank");
    }
    else
    {
    //先将tabControl1隐藏然后remove掉目标tab(如果不隐藏则出现闪烁,即系统自动调转到tabControl1的第一个tab然后跳会。)最后显示tabControl1。
    #p#分页标题#e#
    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];
    tabControl1.Visible = true;
    }
    }
    #endregion

    说明:当双击当前Tabpage从而关闭当前页面时,tabControl1 会首先定位到第一个tab然后再定位到指定的Tabpage上,我采取隐藏tabControl1-处理-显示tabControl1思路解决此问题。

    总结

    分页浏览器所谓"分页",从实现上讲就是"控件的动态添加",当前浏览器产生新窗体时,先new出一个TabPage,再new一个WebBrowser,把这个WebBrowser加载了一些事件以后添加到先前的这个TabPage上,然后把这个TabPage添加到"主窗体"tabControl1中。

    不足之处

    最大的不足:

    用((WebBrowser)sender).StatusText无法捕获的url(例如StatusText 为"javascript:void(0)")目前无法解决这也是某些莫名其妙的问题的出处。另外某些脚本不支持。其他一些罪状让我们共同罗列…


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多