基于MFC的网络浏览器Demo
来源:互联网 发布:vb.net excel教程 编辑:程序博客网 时间:2024/05/01 09:53
最近在接触C++的HTTP编程,做了一个网络浏览器,仅仅是一个demo版本的,呵呵。下面先介绍一下HTTP的工作原理
HTTP
在介绍HTTP原理之前,不得不提及一位有关Internet的大师级人物,英国计算机科学家蒂姆·伯纳斯·李(Tim Berners-Lee),他发明了web浏览器,使得Internet的应用变得非常广泛,Internet的发展也就进入了万维网时代。万维网(World Wide Web,WWW或3W)是基于http协议的一种网络应用,其主要组成有两部分:一是组成万维网的超链接文档(HTML文档);二是超链接文档的传输协议,即HTTP(Hypertext Transfer Protocol)。在Internet中工作的主机,当要访问万维网的某个网页时,大致经历以下几个步骤(该过程对用户是透明的):
- 用户首先要确定网页文件所在的URL(统一资源定位符),由URL唯一确定用户要访问的文件在Internet上的位置;
- 浏览器向DNS(域名服务器)发出请求,要求把相应的域名转化为IP地址;
- DNS进行查询后,向浏览器发出应答,回复相应的IP地址;
- 在查询得到该网页所在的服务器IP后,就进入HTTP的工作阶段。浏览器向该IP地址的主机发出与端口80建立一条TCP连接的请求(端口80是服务器提供web服务的默认端口);
- 连接建立成功后,浏览器发出一条请求传输网页的HTTP命令。格式为GET/待访问的网页文件;
- 当改域名的服务器收到请求后,向浏览器发送相应的待访问的网页文件;
- 发送完成后,由服务器主动关闭TCP连接,至此,HTTP的工作过程结束;
- 浏览器显示收到的相应网页文件;若改网页文件中包含图片,则还要与服务器再次建立一个TCP连接以下载图片。
在上述的工作步骤中,对浏览器来说最关键的问题是如何把HTML文档下载到本地的主机上,该任务是由HTTP来完成的,可以认为,HTTP是Web服务的基础。
HTTP即超文本传输协议,1990年提出,目前万维网上使用的主要版本是HTTP/1.0和HTTP/1.1。HTTP工作于客户端-服务器模式(C-S模式),浏览器是客户端,接收连接并对请求返回信息的应用程序是Web服务器。在实际工作时,浏览器相当于一个用户代理(User Agent),用户要求完成的各种操作均由它向Web服务器提出,并处理又服务器返回给客户端的响应。
下面介绍一下另外一个概念:URL
URL
URL即统一资源定位符(Uniform Resource Locator,URL),是用来表示从Internet上得到资源位置的访问这些资源的方法。URL给资源的位置提供一种抽象的识别方法,并用这种方法给资源定位。只要能够对资源定位,系统就可以对资源进行各种操作,如存取、更新、替换等。URL相当于一个文件名在网络范围的扩展,可以认为是与Internet相连的机器上的任何可访问对象的一个指针,其组成有如下四部分:
<协议>://<主机>:<端口>/<路径>
呵呵,在进入开发之前,先介绍一下MFC对浏览器开发提供的技术支持。
MFC提供的技术支持
浏览器(Browser)是万维网的客户端浏览程序,可以向Web服务器发送各种请求,并对服务器返回的超文本信息和各种媒体数据格式进行解析、显示和播放。目前,PC上常用的浏览器有IE、Mozilla的Firefox、360安全浏览器、腾讯TT浏览器等。从软件开发的角度来看,可以认为浏览器软件的构成有如下两部分:Socket程序和HTTP协议。
MFC(Microsoft Foundation Classes,微软基础类库,一种应用框架)在Windows API的基础上封装了一组C++类,以C++类库的形式构建了面向对象的框架。自然对于浏览器的开发,简单地调用WinSock API即可,呵呵O(∩_∩)O~
从组成上看,网络浏览器一般包括以下几个部分:HTML解释器、HTML执行器和应用程序界面控制。MFC中提供的CHtmlView类能够很好地实现对HTML文档的解释和显示。对于浏览器,除了访问web站点,还可以浏览本地和网络文件系统、维护历史记录等,以上功能均能通过CHtmlView类来实现。
此外,为了方便Internet应用程序,MFC提供了WinInet的封装,该类是一些类和全局函数的集合,包括对HTTP、FTP、Gopher等协议的实现。这样即使不理解TCP/IP协议和套接字编程,也能开发出Internet应用程序。在WinInet提供的类中,主要有以下三种类型:
- 处理Internet会话的类
- 处理Internet连接的类
- 处理文件的类
因此,开发个人版网络浏览器的思路很清晰,利用CHtmlView类的功能,配合使用WinInet提供的接口即可。
在介绍开发浏览器之前,先介绍一下MFC的“文档/视图结构”,呵呵,进入正题如此艰难。
文档/视图结构
文档/视图结构是MFC提供的一种通用的windows程序框架,大多数windows程序采用的都是这种标准框架。其中,文档是应用程序数据基本元素的集合,它构成应用程序锁使用的数据单元,另外还对数据进行管理和维护,通常将数据保存在文档类的成员变量中;视图是数据的用户窗口,为用户提供了文档的可视显示,把文档的部分或者全部内容在窗口中显示出来,视图还提供用户与文档中的数据进行交互的界面,把用户的输入转化为对文档中数据的操作。
常用的文档/视图结构的程序主要有两种:单文档界面(SDI)和多文档界面(MDI)应用程序。
文档/视图结构的提出大大简化了应用程序的设计开发过程,其优点如下:
将数据操作和数据显示、用户界面分离开。
体现了一种“分而治之”的思想,使得模块划分更加合理、独立性更强,同时也简化了数据操作、显示和用户界面工作。文档只负责用户管理,不涉及用户界面;视图只负责数据输出与用户界面的交互,可以不考虑应用程序的数据是如何组织的,甚至文档中的数据结构发生变化时也不必改动视图的代码;MFC在文档/视图结构上集成了很多标准操作界面,包括新建、打开、保存等,减少了开发人员的工作量;
- 支持打印预览和电子邮件发送功能。
下面进入正题。开发个人版本的网络浏览器
开发步骤
1.创建文档/视图工程,选择单个文档,具体设置如下:
在高级功能中无需勾选Windows套接字,因为在CHtmlView类中已经封装了IE内核,已经包含Socket功能,不需要单独去实现。最后一步生成的视图类的基类选择CHtmlView,必须使视图类继承自CHtmlView类。
2.添加地址栏
设置在资源视图中的Dialog中设计地址栏如下:
为GO按钮添加事件处理程序如下:
CString sWebAddress; //获取编辑框用户输入的web地址m_wndDlgBar.GetDlgItem(IDC_EDIT_ADDRESS)->GetWindowText(sWebAddress); //浏览相应的网页((CHtmlView *)GetActiveView())->Navigate(sWebAddress);
其中,Navigate方法是CHtmlView类的常用方法之一,用于获取指定网址的页面,并将其返回给视图。
一般情况下,用户在地址栏输入网址后,并不一定要点击“GO”按钮,大多数情况下会选择按回车键。因此可以考虑添加识别回车的事件,这要用到windows程序内置的消息映射机制。具体实现如下:
在MainFrm.h中声明消息映射函数 afx_msg void OnInputAddress();
在MainFrm.cpp中添加消息映射 ON_COMMAND(IDOK,OnInputAddress)
具体位置如下:
3.设计主菜单
一般的浏览器都有“前进”、“后退”、“停止”、“刷新”、“转到主页”等网页导航功能,这些在CHtmlView类中均有相应的实现函数,直接调用即可。
菜单设计如下:
可以为每个菜单选项的Prompt属性添加相应的内容,实现鼠标悬停提示功能,如:对于“后退”菜单,对其添加Prompt属性:转到上一页\n后退
其中,Prompt属性“\n”之前的文字用于指定选定菜单项时出现在状态栏的文本,“\n”之后的文字则是鼠标放在工具栏对应功能按钮上时出现的提示文本。
为“后退”子菜单添加事件处理程序如下:
CSelfBrowserView::GoBack();//后退
在CHtmlView类的方法列表中已经实现了GoBack、GoForward、GoHome等这些浏览器通用的基本功能,直接调用即可。为其他菜单分别添加事件处理程序如下:
void CSelfBrowserView::OnForward(){ // TODO: 在此添加命令处理程序代码 CSelfBrowserView::GoForward();//前进}void CSelfBrowserView::OnHome(){ // TODO: 在此添加命令处理程序代码 CSelfBrowserView::GoHome();//主页}void CSelfBrowserView::OnStop(){ // TODO: 在此添加命令处理程序代码 CSelfBrowserView::Stop();//停止}void CSelfBrowserView::OnRefresh(){ // TODO: 在此添加命令处理程序代码 CSelfBrowserView::Refresh();//刷新}
4.自定义工具栏
设计工具栏如下:
设计工具栏时,相应的图标ID选择为上述对应菜单的ID。
为了实现地址栏的同步更新功能,可以为视图类添加OnDocumentComplete方法,浏览器接收到服务器发来的新页面内容时就执行这个方法,添加如下代码:
// 每次当前页面改变,更新地址栏的内容和窗口的标题 ((CMainFrame *)GetParentFrame())->SetURL(lpszURL); GetDocument()->SetTitle(lpszURL);
这里调用SetURL()自定义的函数,在视图类的实现文件中添加头文件声明:
#include "MainFrm.h"
在MainFrm.h中声明该方法。
在MainFrm.cpp中实现SetURL()方法如下:
void CMainFrame::SetURL(LPCTSTR lpszURL){ m_wndDlgBar.GetDlgItem(IDC_EDIT_ADDRESS)->SetWindowText(lpszURL);}
5.拓展功能
除了基本功能外,一般浏览器还有很多拓展功能。用WinInet类可以实现很多拓展功能,下面实现一个“查看网页源代码”的功能。
新设计一个对话框如下:
新建一个MFC类,命名为CHtmlCodeViewDlg,对话框类选择刚刚设计的对话框的ID,实现新添加的类与设计的对话框关联起来。
为菜单“源文件”菜单项添加事件处理程序如下:
void CSelfBrowserView::OnCode(){ // TODO: 在此添加命令处理程序代码 CHtmlCodeViewDlg dlg; dlg.DoModal();//生成显示网页HTML源码的对话框}
OnCode函数过程的代码只是生成了用于显示网页源码的对话框窗体对象,而显示源码的过程需要对话框自身去实现,该实现过程要放在初始化代码中,因此需要为CHtmlCodeViewDlg类添加初始化过程如下:
其初始化,添加代码如下:
// TODO: 在此添加额外的初始化 CWaitCursor wait; //等待 CInternetSession session("Self Net"); //新建会话 CStdioFile *pFile=NULL; CString sWebAddress; //从地址栏获取URL (((CMainFrame *)GetParentFrame())->m_wndDlgBar).GetDlgItem(IDC_EDIT_ADDRESS)->GetWindowTextA(sWebAddress); pFile = session.OpenURL(sWebAddress); //打开URL if(pFile != NULL) { CString str,allText,crlf="\r\n"; //回车换行 while(pFile->ReadString(str)) //读入页面内容 { allText+=crlf + str; } this->m_htmlCode = allText; UpdateData(false); //在对话框中显示网页源码 pFile->Close(); //关闭文件 } session.Close(); //关闭会话
至此,该Demo版本的网络浏览器开发已经结束。
运行效果如下:
工程源码
下载
- 基于MFC的网络浏览器Demo
- VS2010 基于MFC的扫雷demo
- [MFC] 入门级demo:基于MFC的五子棋程序
- 基于Socket的MFC网络编程
- MFC 基于消息机机制的WSAAsyncSelect demo
- (MFC)基于CPU和硬盘号的加密程序demo
- iPhone SDK Demo - CF Socket 简介和基于Socket+Http打造自己的浏览器Demo
- 基于MFC的VC++仿QQ浏览器源码(雏形)
- 一个基于线程池的网络处理服务器demo
- MFC基于socket的网络聊天室的实现
- Android笔记 网络源代码浏览器demo
- 基于socket的网络通信实现(MFC)
- 基于IE内核的浏览器:WebBrowser上的网页与Winform本身交互[Demo下载]
- 基于VS2010的MFC对话框编程之图片浏览器(附源代码)
- 基于MFC的DLL
- 基于浏览器的Linux
- 基于浏览器的Linux
- 基于浏览器的Linux
- mysql基础2【常用mysql语句】
- VS2010编译LLVM(制作Lib文件)
- Python中使用中文
- Leetcode常用五大算法思想
- 寻找遗失的ghs.google.com
- 基于MFC的网络浏览器Demo
- ubuntu14.10下面装wine .sourceInsight
- C# Linq 交集、并集、差集、去重
- HDU 2570 迷瘴 (贪心)
- 将WebBrower置为可编辑状态
- eclipse两个比较好用的功能
- 监听socket被子进程继承导致的通信问题
- python opencv face detection
- C++ map,set内部数据结构