《梅芳-网络编程实用教程-第8章》由会员分享,可在线阅读,更多相关《梅芳-网络编程实用教程-第8章(67页珍藏版)》请在金锄头文库上搜索。
1、第第8章章 HTTP协议及高级编程协议及高级编程简要介绍HTTP协议。介绍MFC中的CHtmlView类。使用CHtmlView类,创建一个Web浏览器型的应用程序。8.1 HTTP协议协议HTTP是 超 文 本 传 输 协 议 ( HypertextTransferProtocol)的简称,HTTP协议也是基于TCP/IP的客户/服务器协议。1990年,在万维网应用的开发中,为了解决HTML文档在网上的传输问题,诞生了HTTP协议。至今已有了三个版本,HTTP0.9,HTTP1.0以及HTTP1.1。为了适应下一代的因特网,还出现了HTTPng。事实证明,HTTP比以前的任何一种协议都简单有
2、效,能将信息很好地组织起来,让人们方便地、直接地从Internet上检索和获取所需的信息。8.1.1 HTTP的基本概念的基本概念RFC2068是HTTP1.1的最新的详细描述,本节介绍HTTP的基本概念。图8.1HTTP的会话过程HTTP的会话周期由连接、请求、响应和断开4个阶段组成:(1)建立TCP/IP连接(TCP/IPconnection)(2)Web客户向服务器发送HTTP请求(HTTPrequest)(3)服务器向客户回送HTTP响应(HTTP response)(4)断开TCP/IP连接(disconnection)HTTP协议就是规定了Web客户和服务器之间的信息交换规程,以及
3、HTTP请求和HTTP响应消息的内容和格式。HTTP协议应在Web浏览器和Web服务器中实现。换句话说,Web浏览器和Web服务器应按照HTTP协议交换信息。8.1.2 HTTP协议的应用协议的应用HTTP协议对编程有什么用?能够实现什么样实用的程序?这些问题使我们不得不回到HTTP的本质。超文本传输协议,主要是用于传输文件的协议。虽然RFC2068对HTTP协议描述早就超出了文件传输的范围。但是传输文件的作用还是最主要的。在这里我们提出几个问题,这些问题都可以使用HTTP协议编程实现。比如:基于HTTP的文件断点续传的程序使用代理服务器下载的程序Web服务器程序能够通过身份认证而下载文件的程
4、序接受浏览器网页上载文件的程序这些功能的实现都要求用户对HTTP比较了解。8.2 利用利用CHtmlView类创建类创建Web浏览器型浏览器型的应用程序的应用程序8.2.1 CHtmlView类类与与WebBrowser控控件件CHtmlView类在afxhtml.h包含文件中定义,是从CView派生的,如图8.2所示。在标准的MFC框架应用程序中,无论是基于SDI或MDI的,所有从CView派生的类,都提供了由CView提供的功能。图8.2CHtmlView类的继承关系CHtmlView类的主要功能是访问Web网站和HTML文档。这是由于CHtmlView类在MFC的文档/视图结构(MFCs
5、document/viewarchitecture)环境中,进一步提供了WebBrowser控件的功能,可以说CHtmlView类是对WebBrowser控件的封装。WebBrowser控件支持通过超链接和统一资源定位器URL导航的Web浏览。CHtmlView提供的WebBrowser使得应用程序成了一个Web浏览器(webbrowser)。要创建一个Web浏览器型的应用程序,可以使用CHtmlView类。通过MFC应用程序向导实现。8.2.2 CHtmlView 类的成员函数类的成员函数1获取和设置属性(获取和设置属性(Attributes)的成员函数的成员函数(1)CStringGetT
6、ype()const;返回浏览器包含的文档类型名字符串(2)longGetLeft()const;返回浏览器左边界据屏幕左边缘的象素值voidSetLeft(longnNewValue);设置浏览器左边界的象素值(3)longGetTop()const;返回浏览器上边界据屏幕上边缘的象素值voidSetTop(longnNewValue);设置浏览器上边界的象素值(4)longGetHeight()const;返回浏览器高度的象素值voidSetHeight(longnNewValue);设置IE窗口的象素值(5)BOOLGetVisible()const;获取对象是否可见,0表示隐藏,非0可
7、见voidSetVisible(BOOLbNewValue);设置对象是否可见(6)BOOLGetOffline()const;返回浏览器的操作是离线还是在线voidSetOffline(BOOLbNewValue);设置浏览器的离线或在线的操作方式(7)CStringGetLocationName()const;返回浏览器中显示的资源的名字(8)BOOLGetSilent()const;获取在浏览器中是否显示对话框,返回0表示显示voidSetSilent(BOOLbNewValue);设置在浏览器中是否显示对话框,默认为0(9)BOOLGetTopLevelContainer()const
8、;获当前取对象是否为顶级容器,非0为顶级BOOLGetLocationURL()const;获取当前浏览器中的资源的URL串 其它的函数就不一一列举了其它的函数就不一一列举了2主要的操作(主要的操作(Operations)成员函数成员函数这些成员函数非常有用,常常用在应用程序中。void GoBack( ); 导 航 到 历 史 列 表 的 前 一 个 条 目(previousitem)。voidGoForward();导航到历史列表的下一个条目。voidGoHome();导航到主页,该主页在IE的属性中设置。voidGoSearch();导航到当前搜索页。该页在IE的属性中设置。voidRe
9、fresh();重新装入浏览器当前正在显示的URL或者文件,即刷新。voidStop();撤销任何未完成的导航或下载,并且停止任何动态的页面元素,例如背景音乐和动画。Navigate导航到由URL指定的资源。Navigate2导航到由URL指定的资源或者由全路径指定的文件。PutProperty设置与所给定的对象相关属性的当前值GetProperty返回与所给定的对象相关属性的当前值ExecWB执行一个命令。LoadFromResource 在WebBrowser控件中装入一个资源。后面的六个函数的调用格式比较复杂,下面分别叙述(1)第一种格式的导航函数调用这个成员函数,导航到由URL指定的资
10、源,或者由一个完全的路径指定的文件。voidNavigate(LPCTSTRURL,DWORDdwFlags=0,LPCTSTRlpszTargetFrameName=NULL,LPCTSTRlpszHeaders=NULL,LPVOIDlpvPostData=NULL,DWORDdwPostDataLen=0);(2)第二种格式的导航函数Navigate2导航到由URL指定的资源,或者由一个完全的路径指定的文件。函数通过支持特定文件夹的浏览,诸 如 , Desktop 和 My Computer, 扩 展 了Navigate成员函数的功能,它们由参数pIDL指定。函数有三种重载的形式,参数有
11、所不同。voidNavigate2(LPITEMIDLISTpIDL,DWORDdwFlags=0,LPCTSTRlpszTargetFrameName=NULL);voidNavigate2(LPCTSTRlpszURL,DWORDdwFlags=0,LPCTSTRlpszTargetFrameName=NULL,LPCTSTRlpszHeaders=NULL,LPVOIDlpvPostData=NULL,DWORDdwPostDataLen=0);voidNavigate2(LPCTSTRlpszURL,DWORDdwFlags,CByteArray&baPostedData,LPCTST
12、RlpszTargetFrameName=NULL,LPCTSTRlpszHeader=NULL);(3)设置属性的成员函数设置一个给定对象相关的属性。有多种重载的形式,参数不同。voidPutProperty(LPCTSTRlpszProperty,constVARIANT&vtValue);voidPutProperty(LPCTSTRlpszPropertyName,doubledValue);void PutProperty( LPCTSTR lpszPropertyName, longlValue);voidPutProperty(LPCTSTRlpszPropertyName,LP
13、CTSTRlpszValue);voidPutProperty(LPCTSTRlpszPropertyName,shortnValue);(4)获得属性得到与控件相关的属性值,有两种重载的形式。BOOLGetProperty(LPCTSTRlpszProperty,CString&strValue);COleVariantGetProperty(LPCTSTRlpsz);前者返回非零,表示成功完成,否则返回0,后者返回COleVariant对象。(5)执行命令ExecWB调用这个成员函数来在浏览器控件中或IE中执行一个命令。voidExecWB(OLECMDIDcmdID,OLECMDEXEC
14、OPTcmdexecopt,VARIANT*pvaIn,VARIANT*pvaOut);(6)装入资源调用此成员函数来将指定的资源装入浏览器控件,有两种形式。BOOLLoadFromResource(LPCTSTRlpszResource);BOOLLoadFromResource(UINTnRes);3事件(事件(Events)处理函数处理函数为 了 利 用 Windows的 消 息 驱 动 机 制 ,CHtmlView类定义了许多可重载的事件处理函数,当一定的事件发生时,MFC框架会自动调用相应的事件处理函数。用户可以重载这些函数,添加自己的代码,实现应用程序特定的功能。下面列举了一些,详
15、细的资料可查阅MSDN文档。OnNavigateComplete2对于一个窗口或显示框架,完成到一个超链接的导航后,调用此函数OnBeforeNavigate2对于一个窗口或显示框架,在给定的Web浏览器中,一个导航出现之前,调用此函数virtual void OnStatusTextChange( LPCTSTRlpszText);当与WebBrowser控件相关的状态栏的文本改变时,调用此函数,参数lpszText包含新的状态栏文本的字符串。virtualvoidOnVisible(BOOLbVisible);当WebBrowser的窗口应当被显示或隐藏时,框架调用此函数,bVisible
16、表示了窗口的状态,:如果为非零,对象可见;为零,对象不可见。virtualvoidOnToolBar(BOOLbToolBar);当 ToolBar 属性已经改变时,调用此函数,bToolBar为非零,IE的工具栏是可见的;否则相反。virtualvoidOnMenuBar(BOOLbMenuBar);当MenuBar属性已改变时,调用此函数。bMenuBar为非零,菜单栏可见;否则相反。8.2.3 创创建建一一个个Web浏浏览览器器型型的的应应用用程程序序的的一一般般步骤步骤1利利用用MFC AppWizard创创建建SDI或或MDI应应用用程序程序前几章创建的都是基于对话框的程序,Web浏
17、览器型的应用程序一般是单文档或多文档的程序。利用MFC应用程序向导创建SDI或MDI应用程序需要经过6步,你可以回到前一步或进到后一步来改变你已经选择过的选项。在每一步,对每一个选项都可以得到帮助,右击控件,可以得到关于每个选项控件的信息。在VC+集成开发环境中点菜单File/New.,出现新工程对话框,如图8.3。图8.3创建新工程的对话框选择MFCAppWizard.exe类型的工程,输入工程的名字,决定工程文件存放的位置,然后点击OK按钮,出现第一步对话框。如图8.4。(1)第一步:选择应用程序结构图8.4第一步:选择应用程序结构为应用程序选择三种结构之一,单文档(SingleDocum
18、entSDI),多文档(MultipleDocumentMDI),基于对话框(DialogBased)。Web浏览器型的应用程序一般选择SDI类型,以下的操作都假定选择了SDI类型。决定应用程序是否要支持MFC的文档/视图结构(document/viewarchitecture),实际你必须选择支持,因为不支持文档/视图结构的应用程序不能打开磁盘文件和从CWnd类继承的窗口区,并且后面的步骤都是无效的。选择资源中的文本所使用的语言,应选择“中文中国”。作完这三件事以后,点击Next按钮,出现第二步对话框。如图8.5。(2)第二步:选择应用程序支持的数据库图8.5第二步:选择应用程序支持的数据库
19、为程序选择一种数据库支持,有四个选项。没有(None),头文件支持(Headerfilesupport),带有文件支持的数据库视图(DatabaseViewwithfile support)或没有文件支持的数据库视图(DatabaseViewwithoutfilesupport)。如果选择了数据库支持,点击数据源(DataSource),在外部ODBC数据库、DAO数据库和OLEDB数据库中选择一个,然后选择相应的数据源和数据库表选项。点击Next按钮,出现第三步对话框,如图8.6。(3)第三步:选择应用程序支持的复合文档图8.6选择应用程序支持的复合文档选择应用程序支持的复合文档(compo
20、unddocument)类型。有五个选项:None:不支持复合文档Container:容器,一个OLE2.0风格的文档容器。Mini-server:最小服务器,一个OLE服务器,但不能作为一个独立的程序来运行。Full-server:完全服务器,一个OLE服务器,可以作为独立程序运行。Bothcontainerandserver:容器和服务器两者。也可以选择选项来启用标准的ActiveX资源,增加额外的自动命令到应用程序的菜单条中。点击Next按钮,出现第四步对话框,如图8.7。(4)第四步:选择应用程序的接口特性图8.7第四步:选择应用程序的接口特性为程序选择基本的用户接口特性。如快捷的工具
21、条、初始状态栏、打印和打印预览、内容敏感的帮助、3D控件、Windows套接字等,都是复选框。要使用的工具条形式,IE4.0ReBars或者MFC常规的工具条。最近打开的文件列表数目,默认值是4。如果想要修改程序的名字和扩展名,或者为你的程序调整用户接口窗口框架风格,点击Advanced。如图8.8。图8.8设置工程的高级属性点击Next,出现第五步对话框。如图8.9所示。(5)第5步:决定三个问题图8.9第5步:决定三个问题选择工程风格:WindowsExplorer:左边是一个树形视图,右边是一个列表视图。MFCStandard:为文件视图提供一个区域。选择是否希望应用程序向导在源文件中产
22、生注释,以便指导你编写程序。选择使用MFC库的选项AsasharedDLL:库作为共享的DLLAsastaticallylinkedlibrary:库作为静态链节的DLL注意,静态链接到MFC的库仅仅在VC+的专业版和企业版中支持(ProfessionalandEnterpriseEditions)。点击Next,出现MFCAppWizardStep6of6对话框。如图8.10。(6)第6步:决定类名和基类图8.10第6步:决定类名和基类如果想要改变默认的由应用程序向导提供的类名,基类,头文件,或者实现文件的名字,输入新的名字,要改变基类,选择你的程序的视图类。点击Finish按钮,出现New
23、ProjectInformation对话框。如图8.11。说明了应用程序的类型,创建的类、应用程序的特性和工程的目录。点击OK按钮,工程创建成功,进入VC+集成的开发环境。图8.11新工程的信息2创建一个创建一个Web浏览器型的应用程序浏览器型的应用程序使用MFCAppWizard可以创建一个Web浏览器型的应用程序。遵照使用MFC应用程序向导创建SDI或MDI的.exe程序的六个步骤。应用程序必须是基于MFC的文档/视图结构的,要注意的是,在第六步,使用Baseclass下拉列表框,必须选择CHtmlView类作为视图类的基类。其他步骤根据应用程序的需要来决定,大部分使用默认值就可以了。CH
24、tmlView类扮演一个Web浏览器控件的封装器,给你的应用程序一个视图来显示Web或HTML页面。向导在该视图类中对OnInitialUpdate函数创建了一个重载。providinganavigationallinktotheMicrosoftVisualC+Website:voidCWebView:OnInitialUpdate()CHtmlView:OnInitialUpdate();/TODO:Thiscodenavigatestoapopularspotontheweb./changethecodetogowhereyoudlike.Navigate2(_T(http:/ 定 应
25、用 程 序 是 否 要 支 持 MFC的 文 档 /视 图 结 构(document/viewarchitecture),你必须选择支持。为文本选择一种语言,然后点击Next(2)为基于对话框的程序完成第为基于对话框的程序完成第2步步为程序选择基本的用户界面特性和套接字支持。点击Next。(3)为基于对话框的程序完成第)为基于对话框的程序完成第3步步如果需要源文件中的注释,它会提示需要在哪里添加你自己的代码。选择想要如何使用MFC库,作为共享的DLL。还是静态链接的DLL。(4)为基于对话框的程序完成第为基于对话框的程序完成第4步步如果想要改变应用程序向导提供的默认的类名,头文件名或实现文件名
26、,输入新的名字。点击Finish。8.3 Web浏览器应用程序实例浏览器应用程序实例8.3.1 程序实现的目标程序实现的目标使用CHtmlView类来实现一个应用程序,使之具有Web浏览器的功能,包括浏览网页、前进、后退、返回主页和搜索功能。通过实例,重点掌握利用CHtmlView类开发Web客户端程序的方法。实现的程序界面如图8.12。图8.12myWeb应用程序的界面8.3.2 创建实例程序创建实例程序1利利用用MFC AppWizard生生成成应应用用程程序序框框架架工程名为myWeb,第一步,工程类型为单文档(SDI),中文语言支持。第二步和第三步使用默认值,不需要数据库,也不提供对于
27、复合对象的支持。第四步选择InternetExplorerReBars工具栏的风格,这样就有了用来输入网址的文本框。第五步不作任何修改,第六步应选择CHtmlView类作为视图类的基类。生成的工程框架包含四个类:应用程序类,CMyWebApp,对应myWeb.h和myWeb.cpp文件。 框架类,CMainFrame,对应MainFrm.h和MainFrm.cpp文件。文档类,CMyWebDoc,对应myWebDoc.h和myWebDoc.cpp文件。HtmlView类 , CMyWebView, 对 应myWebView.h和myWebView.cpp文件。此时编译运行,程序已经具有了基本的
28、Web浏览功能,能自动连到微软的网站。2修改菜单修改菜单修改菜单,添加用户需要的功能条目。在工作区中选择ResourceView卡,选择Menu,双击菜单控件的名字(IDR_MAINFRAME),右边出现程序的菜单。点击菜单中的“查看”项,已经有了“工具栏”和“状态栏”两个条目,双击下面的空框,弹出设置菜单条目属性对话框,如图8.13所示,按照表8.1添加六个菜单条目。图8.13设置菜单条目属性的对话框表8.1要添加的菜单条目菜单条目名称(Caption)ID号前进ID_FOWARD后退ID_BACK停止ID_STOP刷新ID_UPDATE主页ID_HOMEPAGE搜索ID_SEARCH3修改
29、工具栏修改工具栏在工具栏上增加新的按钮,以便快速执行所需的功能。在工作区中选择ResourceView卡,选择ToolBar,双击工具条控件的名字(IDR_MAINFRAME),右边出现程序的工具条。双击其中的按钮,可以看到它们的属性。其中有一个空的按钮,双击它可以添加新的按钮的属性,如图8.14,利用右边的图形绘制工具,可以自己设计新按钮的图样。按照表8.1添加六个按钮,它们的ID号与相应的菜单条目相同。拖动按钮,可以改变按钮之间的相对位置。4为控件添加事件处理函数为控件添加事件处理函数当用户点击菜单条目,或者点击相应的快捷按钮时,应能引起程序的反映,这就需要给这些控件添加事件处理函数。进入
30、类向导,选择“MessageMaps”卡。在“ClassName”下拉框中选择CMyWebView类,然后按照表8.2,为前述的六个控件添加事件处理函数。表8.2六个控件对应的事件处理函数对象IDMessagesMemberFunctionID_FOWARDCOMMANDOnFoward()ID_BACKCOMMANDOnBack()ID_STOPCOMMANDOnStop()ID_UPDATECOMMANDOnUpdate()ID_HOMEPAGECOMMANDOnHomepage()ID_SEARCHCOMMANDOnSearch()5添加事件处理函数的代码添加事件处理函数的代码在myWe
31、bView.cpp实现文件中,添加上述六个事件处理函数的代码。/前进到下一个网页voidCMyWebView:OnFoward()GoForward();/退到前一个网页voidCMyWebView:OnBack()GoBack();/停止网页的下载voidCMyWebView:OnStop()Stop();/刷新当前的网页voidCMyWebView:OnUpdate()Refresh();/回到主页voidCMyWebView:OnHomepage()GoHome();/进行搜索voidCMyWebView:OnSearch()GoSearch();此时可以再编译运行,应当没有问题。6为应
32、用程序添加为应用程序添加URL定位功能定位功能至此,应用程序还无法浏览用户想要的网页,还没有URL定位功能。通过以下步骤来添加这个功能。(1)添加网址输入栏控件在建立应用程序框架时,曾选择了Internet ExplorerReBars的工具条风格,这就自动在程序的资源中添加了一个对话框条,可以将它变为一个网址的输入栏。在工作区中选择ResourceView卡,选择Dialog,双击对话框控件的名字(IDR_MAINFRAME),右边出现这个对话框条。在上面添加一个“地址:”的静态文本,再添加一个文本编辑框控件,ID号是IDC_ADDR,作为地址栏,提供给用户输入要浏览的网站地址。(2)添加控
33、制代码设想当用户在地址栏中输入网址后,打回车键时,浏览器应用程序就下载并显示指定的新网页,为了实现这个功能,考虑到用户在文本编辑框中按下回车键后,会有一个IDOK的消息发送到主框架类,可以添加处理这个消息的控制函数,在该函数中,用指定的网址调用Navigate()或者Navigate2()函数,就可以实现对该网页的浏览。在MainFrm.h文件中,添加消息处理函数的声明:public:voidOnNew();在MainFrm.cpp文件中,添加该函数的实现代吗:voidCMainFrame:OnNew()CStringpp;/获得用户在地址栏中输入的URLm_wndDlgBar.GetDlgI
34、tem(IDC_ADDR)-GetWindowText(pp);/浏览指定的网页(CMyWebView*)GetActiveView()-Navigate(pp);其中m_wndDlgBar是代表地址栏文本框所在的对话框条控件的成员变量,是在生成应用程序框架的时候自动创建的,利用它的GetDlgItem方法取得地址栏控件的ID,再利用地址栏控件的GetWindowText方法获得用户输入的网址。另外,由GetActiveView()函数返回的是一个CView类的指针,必须将它强制转换成本应用程序视图类的指针,才能调用Navigate()函数。建立事件处理函数与消息的映射在MainFrm.cpp
35、文件中,再消息映射(MESSAGE_MAP)段中添加自己的消息映射的宏。用ON_COMMAND命令建立IDOK消息和处理函数OnNew的映射关系。BEGIN_MESSAGE_MAP(CMainFrame,CFrameWnd)/AFX_MSG_MAP(CMainFrame)ON_WM_CREATE()/AFX_MSG_MAPON_COMMAND(IDOK, OnNew)/自己的消息映射宏END_MESSAGE_MAP()要注意,自己添加的消息映射宏要放在类向导自动生成的代码之外,一般放在AFX_MSG_MAP宏的后面。在myWebView.h文件的类定义前面添加包含语句#includemyWeb
36、Doc.h经过上述处理,应用程序就可以自由地浏览网页了7解决点击超链接时地址栏的同步问题解决点击超链接时地址栏的同步问题当用户点击网页中的超链接来浏览其他网页时,地址栏中应显示该链接的网址,以便用户能了解自己所在的位置,解决这个问题可以利用CHtmlView类的事件 处 理 函 数 。 当 网 页 下 载 完 成 后 , 会 触 发 OnDocumentComplete()函数,该函数的参数就是所下载网页的URL,可以利用此函数对地址栏进行设置。添加以下代码:在MainFrm.h文件中,添加处理函数的声明:public:voidSetPage(LPCTSTRlpszURL);在MainFrm.
37、cpp文件中,添加该函数的实现代吗:voidCMainFrame:SetPage(LPCTSTRlpszURL)m_wndDlgBar.GetDlgItem(IDC_ADDR)-SetWindowText(lpszURL);该函数页使用了地址栏所在的对话框条控件对应的成员变量,将指定的URL显示在地址栏中。使用类向导添加事件处理函数用 类 向 导 为 应 用 程 序 的 CMyWebView类 添 加 OnDocumentComplete()事件处理函数。并在myWebView.cpp文件中添加它的实现代码void CMyWebView:OnDocumentComplete(LPCTSTRlpszURL)/TODO:Addyourspecializedcodehereand/orcallthebaseclass(CMainFrame*)GetParentFrame()-SetPage(lpszURL);/CHtmlView:OnDocumentComplete(lpszURL);添加包含语句在MainFrm.cpp文件前面添加包含语句#includemyWebView.h在myWebView.cpp文件前面添加包含语句。#includeMainFrm.h至此,编译运行程序,应能很好地运行了。