基于MFC的网络浏览器Demo

最近在接触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中工作的主机,当要访问万维网的某个网页时,大致经历以下几个步骤(该过程对用户是透明的):

  1. 用户首先要确定网页文件所在的URL(统一资源定位符),由URL唯一确定用户要访问的文件在Internet上的位置;
  2. 浏览器向DNS(域名服务器)发出请求,要求把相应的域名转化为IP地址;
  3. DNS进行查询后,向浏览器发出应答,回复相应的IP地址;
  4. 在查询得到该网页所在的服务器IP后,就进入HTTP的工作阶段。浏览器向该IP地址的主机发出与端口80建立一条TCP连接的请求(端口80是服务器提供web服务的默认端口);
  5. 连接建立成功后,浏览器发出一条请求传输网页的HTTP命令。格式为GET/待访问的网页文件;
  6. 当改域名的服务器收到请求后,向浏览器发送相应的待访问的网页文件;
  7. 发送完成后,由服务器主动关闭TCP连接,至此,HTTP的工作过程结束;
  8. 浏览器显示收到的相应网页文件;若改网页文件中包含图片,则还要与服务器再次建立一个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.创建文档/视图工程,选择单个文档,具体设置如下:

基于MFC的网络浏览器Demo_第1张图片
基于MFC的网络浏览器Demo_第2张图片
在高级功能中无需勾选Windows套接字,因为在CHtmlView类中已经封装了IE内核,已经包含Socket功能,不需要单独去实现。最后一步生成的视图类的基类选择CHtmlView,必须使视图类继承自CHtmlView类。
基于MFC的网络浏览器Demo_第3张图片

2.添加地址栏

设置在资源视图中的Dialog中设计地址栏如下:
基于MFC的网络浏览器Demo_第4张图片
为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)
具体位置如下:
基于MFC的网络浏览器Demo_第5张图片

3.设计主菜单

一般的浏览器都有“前进”、“后退”、“停止”、“刷新”、“转到主页”等网页导航功能,这些在CHtmlView类中均有相应的实现函数,直接调用即可。
菜单设计如下:
基于MFC的网络浏览器Demo_第6张图片
可以为每个菜单选项的Prompt属性添加相应的内容,实现鼠标悬停提示功能,如:对于“后退”菜单,对其添加Prompt属性:转到上一页\n后退
基于MFC的网络浏览器Demo_第7张图片
其中,Prompt属性“\n”之前的文字用于指定选定菜单项时出现在状态栏的文本,“\n”之后的文字则是鼠标放在工具栏对应功能按钮上时出现的提示文本。
为“后退”子菜单添加事件处理程序如下:

CSelfBrowserView::GoBack();//后退

基于MFC的网络浏览器Demo_第8张图片
基于MFC的网络浏览器Demo_第9张图片
在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.自定义工具栏

设计工具栏如下:
基于MFC的网络浏览器Demo_第10张图片
设计工具栏时,相应的图标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的网络浏览器Demo_第11张图片
新建一个MFC类,命名为CHtmlCodeViewDlg,对话框类选择刚刚设计的对话框的ID,实现新添加的类与设计的对话框关联起来。
为菜单“源文件”菜单项添加事件处理程序如下:
基于MFC的网络浏览器Demo_第12张图片

void CSelfBrowserView::OnCode()
{
    // TODO: 在此添加命令处理程序代码
    CHtmlCodeViewDlg dlg;
    dlg.DoModal();//生成显示网页HTML源码的对话框
}

OnCode函数过程的代码只是生成了用于显示网页源码的对话框窗体对象,而显示源码的过程需要对话框自身去实现,该实现过程要放在初始化代码中,因此需要为CHtmlCodeViewDlg类添加初始化过程如下:
基于MFC的网络浏览器Demo_第13张图片
其初始化,添加代码如下:

// 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_第14张图片
基于MFC的网络浏览器Demo_第15张图片
工程源码
下载

你可能感兴趣的:(C++,MFC开发,网络编程,浏览器)