基于MFC实现的WEB浏览器

基于MFC实现的WEB浏览器 一,系统设计 1,1 总体设计 本次课程设计所实现的 Web 浏览器首先要实现设计要求中的功能,要有友好的界面,能正常的浏览网页

本文包含相关资料包-----> 点击直达获取<-------

基于MFC实现的WEB浏览器

一、系统设计

1.1 总体设计

本次课程设计所实现的 Web 浏览器首先要实现设计要求中的功能,要有友好的界面,能正常的浏览网页,能实现后退、前进、刷新等基本功能。

此外,在要求的功能之上,对 Web 浏览器的功能进行了扩充,能实现网页保存、打印网页、在网页上查找、选中全部内容、标签式多窗口浏览、关闭浏览器提示、页面缩放、网页加载进度显示、浏览器状态以及界面样式更换等功能。

1.2 详细设计

本 Web 浏览器具有较多的功能,因而采用了模块化的设计思想,将每个功能做成了相应的模块,便于开发。另外由于 Web 浏览器的自身性质,本次开发采用了 MFC 的多文档(MDI)模式,使用 App—MainFrame—ChildFrame—View 的模式开发。 功能模块的关系如下:

1.2.1 用户界面设计

本 Web浏览器的界面采用类似Microsoft Office 2007 的 Ribbon 界面,摒弃了传统的菜单栏与工具栏组合的界面,使用户界面更加友好。其中,Ribbon界面是由微软公司设计开发,并被加入了MFC 类库,因而在 MFC 框架下使用 Ribbon 界面较为容易,并且符合此次课程设计的要求。

考虑到标签式的 Web 浏览器是如今的主流,本 Web 浏览器也采用了这种设计,将每个浏览窗口放入标签中,并在标签上添加了关闭按钮,方便用户操作。另外,标签也支持拖动排序,可以拖动标签来修改页面的先后顺序。另外,Windows7 以及更高版本操作系统推出了任务栏显示缩略图功能,本程序用到了MFC 中的这项功能,限定了现实范围,使任务栏只显示网页的缩略图。并且对多标签页面做了适配,使一个主窗口在任务栏上能同时显示多个标签页的内容。如图所示:

此外,为了丰富界面元素,本 Web 浏览器使用了 Basicset 图标集中的一些图标。另外支持更换界面样式,有 5 套界面皮肤可供选择。界面皮肤更换的代码如下:

c++ void CMainFrame::OnApplicationLook(UINT id) { CWaitCursor wait; theApp.m_nAppLook = id; switch (theApp.m_nAppLook) { case ID_VIEW_APPLOOK_WIN_2000: CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisual Manager)); m_wndRibbonBar.SetWindows7Look(FALSE); break; case ID_VIEW_APPLOOK_OFF_XP CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualMan agerOfficeXP)); m_wndRibbonBar.SetWindows7Look(FALSE); break; case ID_VIEW_APPLOOK_WIN_XP: CMFCVisualManagerWindows::m_b3DTabsXPTheme = TRUE; CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows)); m_wndRibbonBar.SetWindows7Look(FALSE); break; case ID_VIEW_APPLOOK_OFF_2003: CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS( CMFCVisualManagerOffice2003)); CDockingManager::SetDockingMode(DT_SMART); m_wndRibbonBar.SetWindows7Look(FALSE); break; case ID_VIEW_APPLOOK_VS_2005: CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2005)); CDockingManager::SetDockingMode(DT_SMART); m_wndRibbonBar.SetWindows7Look(FALSE); break; case ID_VIEW_APPLOOK_VS_2008: CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerVS2008)); CDockingManager::SetDockingMode(DT_SMART); m_wndRibbonBar.SetWindows7Look(FALSE); break; case ID_VIEW_APPLOOK_WINDOWS_7: CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows7)); CDockingManager::SetDockingMode(DT_SMART); m_wndRibbonBar.SetWindows7Look(TRUE); break; default: CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFC VisualManagerOffice2007)); CDockingManager::SetDockingMode(DT_SMART); m_wndRibbonBar.SetWindows7Look(FALSE); } RedrawWindow(NULL, NULL, RDW_ALLCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW | RDW_FRAME | RDW_ERASE); theApp.WriteInt(_T("ApplicationLook"), theApp.m_nAppLook); }

1.2.2 多标签模块设计

本程序采用的是 MFC 的多文档模式,并对多文档进行了管理,统一到界面的标签上。新建功能是用来创建新的子窗口,并向父窗口注册,显示在标签上。新建窗口分两种情况,一种是用户触发 ID_FILE_NEW 产生的,无论是从 Ribbon 功能区上点击,还是下拉菜单上点击。另外一种是浏览器触发,当浏览器需要弹出新窗口时新建子窗口,这个问题后面会有解决方案的阐述。

使用 CHtmlView 访问网页的时候,经常会出现脚本错误的提示框,本程序采用了对其设置 SetSilent(TRUE)来屏蔽脚本错误提示。

1.2.3 浏览模块设计

浏览模块作为 Web 浏览器的核心部分,设计使需要考虑很多问题。首先是地址栏。地址栏可以接受用户输入网址,并将信息传给 View 模块,使其加载网页。另外,地址栏还需要能显示当前页面的网址,并且切换标签页的时候,地址栏的网址会随之改变。为了实现以上功能,在 MainFrm.cpp 中 OnAddr 用来接受用户数据并处理,ChangeAddr用来修改地址栏内容。OnAddr首先获取地址栏的指针,然后获取用户输入的内容,如果内容非空,再判断输入的内容是否与当前网页地址相同,防止重复加载。不相同的话,再获取当前活动的子窗口,并将网址传递给子窗口的View。代码如下:

c++ void CMainFrame::OnAddr() { CMFCRibbonEdit *pEdit=DYNAMIC_DOWNCAST(CMFCRibbonEdit, m_wndRibbonBar.FindByID(ID_ADDR)); //获取地址输入框 CString strUrl=pEdit->GetEditText(); //获取地址框文本 if(strUrl=="") //数据合法性判断 MessageBox(L"请输入要访问的网址!",L"提示",MB_ICONWARNING); else { CChildFrame *pChildFrame=(CChildFrame*)GetActiveFrame(); CHtmlView *pBrowser=(CHtmlView*)pChildFrame->GetActiveView(); if(pBrowser->GetLocationURL()!=strUrl) pBrowser->Navigate(strUrl); } }

当活动窗口的网页加载完成之后,会执行 OnDocumentComplete 函数,并调用ChangeAddr函数,将改变传递给主框架。同时,通过IHTMLDocument2 接口获取网页标题,并显示在标签上。因为实践测试,GetLocationName方法获取的网页标题并不准确,因而不采用此方法。

OnDocumentComplete 的代码如下:

C++ void CMyView::OnDocumentComplete(LPCTSTR lpszURL) { //浏览器加载完成 CComPtr<IHTMLDocument2> pDoc = (IHTMLDocument2*)this->GetHtmlDocument(); BSTR *bstrTitle; pDoc->get_title(bstrTitle); CString title; title.Empty(); title=*bstrTitle; title=title.Left(20); //只截取前 20 个字符,防止标题过长 GetMainFrame(); //这个函数用来获取主框架和当前子框架的指针 pChildFrame->SetWindowText(title); pMainFrame->ChangeAddr(GetLocationURL()); //调用函数修改 pMainFrame->UpdateFrameTitleForDocument(title); CHtmlView::OnDocumentComplete(lpszURL); }

ChangeAddr的代码如下:

c++ void CMainFrame::ChangeAddr(CString str) { //修改地址输入框文本 CMFCRibbonEdit *pEdit=DYNAMIC_DOWNCAST(CMFCRibbonEdit,m_wndRibbonBar.FindByID(ID_ADDR)); pEdit->SetEditText(str); }

此外,CHtmlView 类有个需要注意的地方,当有新窗口打开时,它会默认调用 IE 打开新窗口。因而需要对其WM_NEWURL 消息进行处理,使其在新标签页打开。代码如下:

c++ ON_MESSAGE(WM_NEWURL, &CMainFrame::OnNewUrl) //消息映射 afx_msg LRESULT CMainFrame::OnNewUrl(WPARAM wParam, LPARAM lParam) { //CHtmlView 类打开了新窗口 LPDISPATCH* ppDispatch=(LPDISPATCH*)wParam; SendMessage(WM_COMMAND, ID_FILE_NEW, 0); CChildFrame* pChildFrame = (CChildFrame*)GetActiveFrame(); *ppDispatch=((CHtmlView*)pChildFrame->GetActiveView())->GetApplication(); return 0; }

同时处理 CHtmlView 的 OnNewWindow2 事件。代码如下:

c++ void CMyView::OnNewWindow2(LPDISPATCH* ppDisp, BOOL* Cancel) { //浏览器弹出新窗口(自定义消息) ::SendMessage(AfxGetMainWnd()->m_hWnd,WM_NEWURL,(WPARAM)ppDi sp,NULL); *Cancel=TRUE; CHtmlView::OnNewWindow2(ppDisp, Cancel); }

1.2.4 操作按钮模块设计

操作按钮即指后退、前进、刷新、停止等功能按钮,其中后退、前进需要特殊处理。因为需要判断当前页面是否可以后退、可以前进,并且对按钮发出可用或禁用消息。并且切换标签页时同步后退、前进按钮的状态。后退、前进按钮的状态可利用 OnCommandStateChange 事件判断。代码如下:

c++ void CMyView::OnCommandStateChange(long nCommand, BOOL bEnable) { //设置按钮状态 if(pMainFrame) if(nCommand==CSC_NAVIGATEFORWARD) isForward=bEnable; else if(nCommand==CSC_NAVIGATEBACK) isBack=bEnable; GetMainFrame(); pMainFrame->SetButtonState(isForward,isBack); CHtmlView::OnCommandStateChange(nCommand, bEnable); }

其中 isForward、isBack 是布尔型的成员变量,用于记录状态,并传递给MainFrame。由于CMFCRibbonButton 类没有提供禁用的方法,我们需要自行发送消息来禁用按钮。

MainFrame的相应代码如下:

c++ ON_UPDATE_COMMAND_UI(ID_EDIT_BACK,&CMainFrame::ButtonEnable) ON_UPDATE_COMMAND_UI(ID_EDIT_FORWARD,&CMainFrame::ButtonEnable) void CMainFrame::ButtonEnable(CCmdUI *pCmdUI) { //设置按钮状态 if(pCmdUI->m_nID==ID_EDIT_FORWARD) pCmdUI->Enable(isForward); else if(pCmdUI->m_nID==ID_EDIT_BACK) pCmdUI->Enable(isBack); else pCmdUI->Enable(TRUE); }

另外,后退、前进的功能实现上对按钮状态进行了判断,防止出现意外情况,增强程序的稳定性。代码如下:

c++ void CMyView::OnEditBack() { //浏览器后退 if(isBack) GoBack(); } void CMyView::OnEditForward() { //浏览器前进 if(isForward) GoForward(); }

Web浏览器的刷新、停止功能可直接调用相应方法,主页即访问百度首页,查找、打印、另存为、全选等功能使用的是CHtmlView 的 ExecWB 方法,具体使用方法不再赘述,可参考微软MSDN 的文档。

1.2.5 页面缩放模块设计

页面缩放用到了 CMFCRibbonSlider 类作为缩放控件,通过IHTMLDocument2 接口修改网页 Document 的缩放级别。

代码如下:

c++ void CMyView::OnSlider() { //页面缩放 GetMainFrame(); double fZoom=pMainFrame->GetZoom(); CComPtr<IHTMLDocument2> pDoc = (IHTMLDocument2*)this->GetHtmlDocument(); ASSERT(pDoc); CComPtr<IHTMLElement> pElem; pDoc->get_body(&pElem); ASSERT(pElem); CComPtr<IHTMLStyle> pStyle; pElem->get_style(&pStyle); CString str; str.Format(L"zoom:%f;",fZoom); pStyle->put_cssText(str.AllocSysString()); }

1.2.6 状态栏模块设计

浏览器的状态栏使用了CMFCRibbonStatusBar 类,并分为三个 Panel,第一个部分使用CMFCRibbonStatic 类显示浏览器的状态,比如加载图片、完成等。第二个部分使用CMFCRibbonProgressBar 类以进度条的形式显示浏览器加载进度。第三个部分是静态文本,始终显示”CrazyUrus 浏览器”。如图所示:

创建 Panel 对象的代码如下:

c++ m_wndStatusBar.AddDynamicElement(new CMFCRibbonLabel( strTitlePane1,FALSE);); m_wndStatusBar.AddExtendedElement(new CMFCRibbonProgressBar( ID_STATUSBAR_PROGRESS,160),L"进度"); m_wndStatusBar.AddSeparator(); m_wndStatusBar.AddExtendedElement(new CMFCRibbonStatusBarPane (ID_STATUSBAR_PANE2,strTitlePane2, TRUE), strTitlePane2);

当 Web浏览器执行加载过程时,会触发OnProgressChange 事件,同时将当前进度和进度最大值返回。程序将返回的数据传递给 MainFrame 的进度条即可。代码如下:

c++ void CMyView::OnProgressChange(long nProgress,long nProgressMax) { //浏览器进度改变,修改程序的进度条 GetMainFrame(); if(pMainFrame) pMainFrame->SetProgress(nProgress,nProgressMax); CHtmlView::OnProgressChange(nProgress, nProgressMax); }

修改进度条的代码如下:

c++ void CMainFrame::SetProgress(long value,long max) { //设置进度条 if(ProgressBar) { ProgressBar->SetRange(0,max); ProgressBar->SetPos(value); } }

浏览器状态修改原理与进度条类似,当状态改变时会触发 OnStatusTextChange 事件,返回状态内容。代码如下:

c++ void CMyView::OnStatusTextChange(LPCTSTR lpszText) { //浏览器状态改变,修改程序的状态栏 GetMainFrame(); if(pMainFrame) pMainFrame->SetStatusText(lpszText); CHtmlView::OnStatusTextChange(lpszText); }

修改状态文本的代码如下:

c++ void CMainFrame::SetStatusText(LPCTSTR str) { //设置状态栏文本 CString tmp=str; static BOOL isFinish=TRUE; if(StatusBar&&!tmp.IsEmpty()&&isFinish) StatusBar->SetText(str); isFinish=tmp.Find(L"完成",0); }

1.2.7 收藏夹模块设计

收藏夹模块是一个较为简单的模块,因为本浏览器采用了预设的机制,为使用者提供了一些常用的网站,使用者并不能修改收藏夹。目前收藏夹对网站分成了导航、搜索、门户、电子商务、社交和其它几类。每个收藏的网页都对应一个按钮,点击之后会执行相应操作,

Web浏览器执行Navigate 打开相应网页。

1.2.8 窗体关闭模块设计

窗体关闭模块是用来提醒用户,防止用户错误操作的。由于本 Web 浏览器采用了标签式的浏览方式,因而容易出现关闭主窗口导致所有标签页被关闭的情况,所以需要在关闭主窗口时添加提示,告知用户是否关闭所有标签页,或者只关闭当前的标签页。本程序添加了一个对话框窗口 IDD_CLOSE,如图所示:

MainFrame 里的 OnClose 函数映射到消息WM_CLOSE,代码如下:

C++ void CMainFrame::OnClose() { CCloseDlg closeDlg; UINT r=closeDlg.DoModal(); //打开关闭对话框 if(r==IDALL) CMDIFrameWndEx::OnClose(); else if(r==IDCUR) GetActiveFrame()->DestroyWindow(); }

关闭对话框将以模态打开,并利用 EndDialog 函数实现点击不同的按钮返回不同的值。MainFrame根据返回值执行不同的操作,即可实现不同的关闭方式。

此外,为了防止用户厌烦此对话框,本程序添加了一个 CheckBox 控件。如果用户勾选,则不再出现此对话框。

1.3 系统平台、语言和工具

本次课程设计在操作系统为 64 位 Windows 7 的个人计算机上完成,采用C/C++程序设计语言编写代码,Visual Studio 2010 开发和编译程序。由于 MFC 的 Ribbon 界面库具有良好的兼容性,本Web 浏览器程序可在 Windows XP、WindowsVista、Windows 7、Windows 8、Windows8.1 以及更高版本 Windows 操作系统上使用,并且使用了 dll 静态调用技术,运行环境即便缺少 MFC 运行库本程序仍可正常使用。

#二、调试过程及操作说明

##2.1 启动 Web 浏览器

本 Web 的启动方式与其它 Windows 程序无任何区别,双击图标即可启动。如出现缺少dll等情况而无法启动,请请前往微软网站更新MFC 运行库。本程序编译时已经将运行库编译到程序里,上述情况一般不会发生。

2.2 浏览网页

程序启动后,会显示程序的主界面,并自动打开百度首页。如果希望输入网址访问指定网页,请在程序右上角的地址栏中输入网址,并按下回车,浏览器就会在当前窗口加载此网页。如果希望访问收藏家中的网页,可直接点击收藏夹下的按钮或图标,浏览器会在当前窗口加载。如果希望在新窗口打开网页,请先点击“新建”,出现新窗口后再输入网址访问。

此外,本 Web 浏览器提供了一系列对网页的操作,可以使用后退、前进、刷新、停止等功能,直接点击相应按钮即可使用。另外,本Web 浏览器还提供了查找、打印、保存、全选等功能。如果希望将当前网页保存到本地,可以点击“保存”按钮,程序会弹出对话框,选择位置即可保存。如果希望打印网页,可以直接点击“打印”按钮,在打印对话框中配置好参数,即可打印。如果在打印之前希望预览打印效果,可点击“打印”按钮下的小箭头,出现下拉菜单,并点击“打印预览”。如下图所示:

如果在打印之前需要对页面大小进行设置,可在下拉菜单中点击“页面设置”。

如果需要在当前网页查找内容,可点击“查找”,并在对话框中输入内容。

如果感觉页面字体较大或较小,可通过“视图”中的页面缩放功能调整字体大小。拖动滑动条,页面字体大小会随之变化。

2.3 修改界面样式及查看帮助

本Web浏览器提供了5 种界面样式,其中 4 种是类似 Office 2007 的样式,另外1 种是类似 Windows7 画图程序的样式。如需更换程序界面的样式,请点击程序右上角的“样式”按钮,会出现下拉菜单,在下拉菜单中可以选择喜欢的样式。

如果需要帮助,可点击右上角的“帮助”按钮,或者功能区中的“帮助”按钮,即会打开帮助文件。由于此次课程设计时间有限,帮助文件并未编写,打开之后里面并没有实质内容,因而使用过程中需要帮助还请参考此设计报告。

如果需要查看此程序的开发信息,请点击功能区的“关于”按钮,会弹出关于对话框。

2.4 退出程序

退出程序的方式有三种,一是直接在主窗口点击右上角的关闭按钮,程序会弹出关闭对话框(参见图 ),点击“关闭所有选项卡”即退出程序。二是点击左上角的圆形图标(Windows样式下是下拉箭头),会出现下拉菜单,在下拉菜单中点击“退出”,会直接退出程序。如图所示:

第三种方法是在任务栏上的程序图标,点击右键弹出菜单,在菜单中点击“关闭”,便会弹出的关闭对话框,然后按第一种方法即可退出。

参考文献

  • 基于AJAX的信息聚合系统的研究与实现(武汉理工大学·蒋佳)
  • 基于MVC模式的水利服务平台系统的设计与实现(中山大学·罗晴文)
  • “Things-Cloud-People”:一个“Web of Things”实现方案(华东师范大学·汤承刚)
  • 基于.NET框架的企业应用集成研究和实现(浙江大学·蒋元星)
  • 基于某军用信息系统数据库系统的设计与实现(华北工学院·马巧梅)
  • 基于.NET的Web应用框架的设计与实现(解放军信息工程大学·郭晓峰)
  • 基于.NET框架的Web应用系统开发与研究(武汉理工大学·易隆)
  • 基于NET平台的分层架构与设计模式的设计与实现(电子科技大学·段海清)
  • 基于JSF的Web GIS设计与实现(昆明理工大学·刘波)
  • 基于EJB的J2EE实现技术研究(南京航空航天大学·夏君权)
  • 基于需求语义描述的多平台统一框架的研究与实现(中国海洋大学·辛灿灿)
  • 网上论坛系统设计与实现(西安电子科技大学·胡秉玺)
  • 在线音乐试听新闻浏览网站的设计与实现(大连理工大学·刘炳东)
  • 基于SSH框架和ExtJs框架的资质管理系统的设计与实现(云南大学·职辉)
  • 基于.NET的高校管理系统分析与设计(西南交通大学·张占远)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:源码客栈 ,原文地址:https://m.bishedaima.com/yuanma/35172.html

相关推荐

发表回复

登录后才能评论