引言
很早就有搞一个浏览器的想法了在vs上就试图做过苦于经常会有这种情况出现当自治的浏览器遇到弹出窗口时无法捕获新的弹出窗口于是乎新的弹出窗口仍旧用ie(或其他系统默认浏览器)打开在研究vs的WebBrowser控件时发现有NewWindow事件于是乎兴奋不已决定用这个分页浏览器体验一下vs
实现功能
预览图如下
当前浏览器的另存为打印打印御览页面设置刷新前进后退等等几乎都是控件封装好了的没有几句代码
浏览器的分页功能当浏览器有NewWindow激发时产生新的一页主要依靠NewWindow事件
当前页面的状态例如标题状态栏等
实现过程以及关键点
新建一个vs的windows applaction项目
界面
一个MenuStrip实现最上面的菜单
两个ToolStrip分别是工具栏和地址栏
一个TabControl也就是浏览器的主体了它的每个TabPage就是每一个分页了
一个StatusStrip也就是状态栏了
另外为了使窗体大小变化时控件也随着变化注意使用控件的dock属性
搭成如下界面
顺便说一句和vs不同的是vs把例如
thistoolStripMenuItem = new SystemWindowsFormsToolStripMenuItem();
thissaveasToolStripMenuItem = new SystemWindowsFormsToolStripMenuItem();
thistoolStripSeparator = new SystemWindowsFormsToolStripSeparator();
thisprintToolStripMenuItem = new SystemWindowsFormsToolStripMenuItem();
thisprintPreToolStripMenuItem = new SystemWindowsFormsToolStripMenuItem();
thistoolStripSeparator = new SystemWindowsFormsToolStripSeparator();
thisexitToolStripMenuItem = new SystemWindowsFormsToolStripMenuItem();
这些通过我们拖拽控件系统生成的界面代码分离出来统一放在叫*Designercs文件里了详见事例代码中的FormDesignercs文件
辅助方法
#region //辅助方法
/// <summary>
/// 当在浏览器地址栏敲回车时当前浏览器重定向到指定url(tscbUrlTex)
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
private void tscbUrl_KeyDown(object sender KeyEventArgs e)
{
if (eKeyCode == KeysEnter)
{
newCurrentPageUrl(tscbUrlText);
}
}
/// <summary>
/// 新建空白页
/// </summary>
private void newPage()
{
tscbUrlText = about:blank;
TabPage mypage = new TabPage();
WebBrowser tempBrowser = new WebBrowser();
tempBrowserNavigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
tempBrowserNewWindow += new CancelEventHandler(tempBrowser_NewWindow);
tempBrowserProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
tempBrowserStatusTextChanged += new EventHandler(tempBrowser_StatusTextChanged);
tempBrowserDock = DockStyleFill;
mypageControlsAdd(tempBrowser);
tabControlTabPagesAdd(mypage);
tabControlSelectedTab = mypage;
}
/// <summary>
/// 临时浏览器进度变化事件
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
void tempBrowser_ProgressChanged(object sender WebBrowserProgressChangedEventArgs e)
{
toolStripProgressBarMaximum = (int)eMaximumProgress;
toolStripProgressBarValue = (int)eCurrentProgress;
}
/// <summary>
/// 新建一页并定向到指定url
/// </summary>
/// <param name=address>新一页的浏览器重新定向到的url</param>
private void newPage(string address)
{
TabPage mypage = new TabPage();
WebBrowser tempBrowser = new WebBrowser();
tempBrowserNavigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
tempBrowserNewWindow += new CancelEventHandler(tempBrowser_NewWindow);
tempBrowserStatusTextChanged += new EventHandler(tempBrowser_StatusTextChanged);
tempBrowserProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
tempBrowserUrl = getUrl(address);
tempBrowserDock = DockStyleFill;
mypageControlsAdd(tempBrowser);
tabControlTabPagesAdd(mypage);
}
/// <summary>
/// 获取当前浏览器
/// </summary>
/// <returns>当前浏览器</returns>
private WebBrowser getCurrentBrowser()
{
WebBrowser currentBrowser = (WebBrowser)tabControlSelectedTabControls[];
return currentBrowser;
}
/// <summary>
/// 处理字符串为合法url
/// </summary>
/// <param name=address></param>
/// <returns></returns>
private Uri getUrl(string address)
{
string tempaddress = address;
if ((!addressStartsWith(http://)) && (!addressStartsWith(https://)) && (!addressStartsWith(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 (oldstringLength < TITLE_COUNT)
{
temp = oldstring;
}
else
{
temp = oldstringSubstring( TITLE_COUNT);
}
return temp;
}
/// <summary>
/// 设置"前进""后退"button的可用状态
/// </summary>
private void setStatusButton()
{
backButtonEnabled = getCurrentBrowser()CanGoBack;
forwordButtonEnabled = getCurrentBrowser()CanGoForward;
}
#endregion
说明其中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)
{
ApplicationExit();
}
/// <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)
{
AboutBox myabout = new AboutBox();
myaboutShow();
}
private void tipToolStripMenuItem_Click(object sender EventArgs e)
{
MessageBoxShow(小提示双击分页标题即可关闭当前页面);
}
#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(tscbUrlText);
}
#endregion
说明和菜单栏实现的功能类似也是一些简单的调用仅仅是表现形式不同
初始化
#region//初始化
/// <summary>
/// 初始化
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
private void Form_Load(object sender EventArgs e)
{
initMainForm();
}
/// <summary>
/// 初始化浏览器
/// </summary>
private void initMainForm()
{
TabPage mypage = new TabPage();
WebBrowser tempBrowser = new WebBrowser();
tempBrowserNavigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
tempBrowserNewWindow += new CancelEventHandler(tempBrowser_NewWindow);
tempBrowserStatusTextChanged += new EventHandler(tempBrowser_StatusTextChanged);
tempBrowserProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
tempBrowserDock = DockStyleFill;
tempBrowserGoHome();//和新建空白页不同
mypageControlsAdd(tempBrowser);
tabControlTabPagesAdd(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
{
toolStripStatusLabelText = myBrowserStatusText;
}
}
/// <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)myBrowserParent;
//通过StatusText属性获得新的url
string NewURL = ((WebBrowser)sender)StatusText;
//生成新的一页
TabPage TabPageTemp = new TabPage();
//生成新的tempBrowser
WebBrowser tempBrowser = new WebBrowser();
//临时浏览器定向到新的url
tempBrowserNavigate(NewURL);
tempBrowserDock = DockStyleFill;
//为临时浏览器关联NewWindow等事件
tempBrowserNewWindow += new CancelEventHandler(tempBrowser_NewWindow);
tempBrowserNavigated += new WebBrowserNavigatedEventHandler(tempBrowser_Navigated);
tempBrowserProgressChanged += new WebBrowserProgressChangedEventHandler(tempBrowser_ProgressChanged);
tempBrowserStatusTextChanged+=new EventHandler(tempBrowser_StatusTextChanged);
//将临时浏览器添加到临时TabPage中
TabPageTempControlsAdd(tempBrowser);
//将临时TabPage添加到主窗体中
thistabControlTabPagesAdd(TabPageTemp);
//使外部无法捕获此事件
eCancel = true;
}
/// <summary>
/// 临时浏览器定向完毕
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
private void tempBrowser_Navigated(object sender WebBrowserNavigatedEventArgs e)
{
tscbUrlText = getCurrentBrowser()UrlToString();
WebBrowser mybrowser = (WebBrowser)sender;
TabPage mypage=(TabPage)mybrowserParent;
//设置临时浏览器所在tab标题
mypageText= newstring(mybrowserDocumentTitle);
}
#endregion
说明临时浏览器实际上是用程序的方式先new出一个tempBrowser然后添加到一个分页中去其中这个tempBrowser我称它为临时浏览器其中void tempBrowser_NewWindow(object sender CancelEventArgs e){}事件是比较重要的我认为它是整个程序的核心部分
tabControl事件
#region//tabControl事件
/// <summary>
/// 切换tab
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
private void tabControl_SelectedIndexChanged(object sender EventArgs e)
{
WebBrowser mybor = (WebBrowser)tabControlSelectedTabControls[];
if (myborUrl != null)
{
//地址输入框
tscbUrlText = myborUrlToString();
tabControlSelectedTabText = newstring(myborDocumentTitle);
}
else
{
tscbUrlText = about:blank;
tabControlSelectedTabText = 空白页;
}
setStatusButton();
}
/// <summary>
/// 关闭当前tab
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
private void tabControl_DoubleClick(object sender EventArgs e)
{
//仅仅剩下一个tab时返回
if (tabControlTabPagesCount <= )
{
tabControlSelectedTabText = 空白页;
getCurrentBrowser()Navigate(about:blank);
}
else
{
//先将tabControl隐藏然后remove掉目标tab(如果不隐藏则出现闪烁即系统自动调转到tabControl的第一个tab然后跳会)最后显示tabControl
tabControlVisible = false;
WebBrowser mybor = getCurrentBrowser();
//释放资源
myborDispose();
myborControlsClear();
thistabControlTabPagesRemove(thistabControlSelectedTab);
//重新设置当前tab
tabControlSelectedTab = tabControlTabPages[tabControlTabPagesCount ];
tabControlVisible = true;
}
}
#endregion
说明:当双击当前Tabpage从而关闭当前页面时tabControl 会首先定位到第一个tab然后再定位到指定的Tabpage上我采取隐藏tabControl处理显示tabControl思路解决此问题
总结
分页浏览器所谓分页从实现上讲就是控件的动态添加当前浏览器产生新窗体时先new出一个TabPage再new一个WebBrowser把这个WebBrowser加载了一些事件以后添加到先前的这个TabPage上然后把这个TabPage添加到主窗体tabControl中
不足之处
最大的不足
用((WebBrowser)sender)StatusText无法捕获的url(例如StatusText 为javascript:void())目前无法解决这也是某些莫名其妙的问题的出处另外某些脚本不支持其他一些罪状让我们共同罗列…