使用VS2005的WebBrowser打造簡單分(fēn)頁浏覽器

發布時間:2009年10月13日      浏覽次數:1804 次
引言
很早就有搞一(yī)個浏覽器的想法了,在vs2003上就試圖做過,苦于經常會有這種情況出現:當自治的浏覽器遇到彈出窗口時無法捕獲新的彈出窗口,于是乎新的彈出窗口仍舊(jiù)用ie(或其他系統默認浏覽器)打開(kāi),在研究vs2005的WebBrowser控件時發現有NewWindow事件,于是乎興奮不已,決定用這個分(fēn)頁浏覽器體(tǐ)驗一(yī)下(xià)vs2005。
實現功能
預覽圖如下(xià):
當前浏覽器的"另存爲","打印","打印禦覽","頁面設置",刷新,前進,後退等等。幾乎都是控件封裝好了的,沒有幾句代碼。
浏覽器的分(fēn)頁功能。當浏覽器有NewWindow激發時産生(shēng)新的一(yī)頁。主要依靠NewWindow事件。
當前頁面的狀态。例如标題,狀态欄等。
實現過程以及關鍵點
新建一(yī)個vs2005的windows applaction項目
界面
一(yī)個MenuStrip實現最上面的菜單。
兩個ToolStrip分(fēn)别是工(gōng)具欄和地址欄。
一(yī)個TabControl也就是浏覽器的主體(tǐ)了,它的每個TabPage就是每一(yī)個分(fēn)頁了。
一(yī)個StatusStrip也就是狀态欄了。
另外(wài)爲了使窗體(tǐ)大(dà)小(xiǎo)變化時控件也随着變化注意使用控件的dock屬性。
搭成如下(xià)界面:
順便說一(yī)句和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();
這些通過我(wǒ)(wǒ)們拖拽控件,系統生(shēng)成的界面代碼分(fēn)離(lí)出來統一(yī)放(fàng)在叫*.Designer.cs文件裏了,詳見事例代碼中(zhōng)的Form1.Designer.cs文件。
輔助方法
#region //輔助方法
/// <summary>
/// 當在浏覽器地址欄敲"回車(chē)"時當前浏覽器重定向到指定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>
/// 新建空白(bái)頁
/// </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>
/// 新建一(yī)頁并定向到指定url
/// </summary>
/// <param name="address">新一(yī)頁的浏覽器重新定向到的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
說明:其中(zhōng)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("小(xiǎo)提示:雙擊分(fēn)頁标題即可關閉當前頁面。");
}
#endregion
#endregion
說明:其中(zhōng)文件菜單的功能大(dà)都是WebBrowser控件封裝好的僅僅是用上文提到的getCurrentBrowser()獲取一(yī)下(xià)當前浏覽器罷了。
工(gōng)具欄
#region//工(gōng)具欄
/// <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>
/// 新建空白(bái)頁
/// </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
說明:和菜單欄實現的功能類似,也是一(yī)些簡單的調用,僅僅是表現形式不同。
初始化
#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();//和新建空白(bái)頁不同
mypage.Controls.Add(tempBrowser);
tabControl1.TabPages.Add(mypage);
}
#endregion
說明:分(fēn)頁浏覽器初始化時要定向到主頁,雖然我(wǒ)(wǒ)們的浏覽器暫時沒有提供設置主頁的功能。
臨時浏覽器事件
#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>
/// 臨時浏覽器産生(shēng)新窗體(tǐ)事件
/// </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;
//生(shēng)成新的一(yī)頁
TabPage TabPageTemp = new TabPage();
//生(shēng)成新的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中(zhōng)
TabPageTemp.Controls.Add(tempBrowser);
//将臨時TabPage添加到主窗體(tǐ)中(zhōng)
this.tabControl1.TabPages.Add(TabPageTemp);
//使外(wài)部無法捕獲此事件
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出一(yī)個tempBrowser然後添加到一(yī)個分(fēn)頁中(zhōng)去(qù)。其中(zhōng)這個tempBrowser我(wǒ)(wǒ)稱它爲臨時浏覽器。其中(zhōng)void tempBrowser_NewWindow(object sender, CancelEventArgs e){..}事件是比較重要的,我(wǒ)(wǒ)認爲它是整個程序的核心部分(fēn)。
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 = "空白(bái)頁";
}
setStatusButton();
}
/// <summary>
/// 關閉當前tab
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void tabControl1_DoubleClick(object sender, EventArgs e)
{
//僅僅剩下(xià)一(yī)個tab時返回
if (tabControl1.TabPages.Count <= 1)
{
tabControl1.SelectedTab.Text = "空白(bái)頁";
getCurrentBrowser().Navigate("about:blank");
}
else
{
//先将tabControl1隐藏然後remove掉目标tab(如果不隐藏則出現閃爍,即系統自動調轉到tabControl1的第一(yī)個tab然後跳會。)最後顯示tabControl1。
tabControl1.Visible = false;
WebBrowser mybor = getCurrentBrowser();
//釋放(fàng)資(zī)源
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 會首先定位到第一(yī)個tab然後再定位到指定的Tabpage上,我(wǒ)(wǒ)采取隐藏tabControl1-處理-顯示tabControl1思路解決此問題。
總結
分(fēn)頁浏覽器所謂"分(fēn)頁",從實現上講就是"控件的動态添加",當前浏覽器産生(shēng)新窗體(tǐ)時,先new出一(yī)個TabPage,再new一(yī)個WebBrowser,把這個WebBrowser加載了一(yī)些事件以後添加到先前的這個TabPage上,然後把這個TabPage添加到"主窗體(tǐ)"tabControl1中(zhōng)。
不足之處
最大(dà)的不足:
用((WebBrowser)sender).StatusText無法捕獲的url(例如StatusText 爲"javascript:void(0)")目前無法解決這也是某些莫名其妙的問題的出處。另外(wài)某些腳本不支持。其他一(yī)些罪狀讓我(wǒ)(wǒ)們共同羅列…
免責聲明:本站相關技術文章信息部分(fēn)來自網絡,目的主要是傳播更多信息,如果您認爲本站的某些信息侵犯了您的版權,請與我(wǒ)(wǒ)們聯系,我(wǒ)(wǒ)們會即時妥善的處理,謝謝合作!