用Socket和MSHTML对象模型创建自己的浏览器

原创 2001年04月30日 10:07:00

                        用Socket和MSHTML对象模型创建自己的浏览器

    薛 瑛  

HTTP协议和WEB浏览器的诞生给我们的网络增加了更多的精彩。但在实际应用中我们可能会有不同的需要而不是单纯的使用浏览器,譬如在我们的应用程序中加入浏览互联网的功能。微软的ChtmlView类很方便的实现了网页浏览。但是它很不灵活,无法使用户动态地在网页上修改自己想要的元素。本文探讨一些方法使用Socket传输Html文档,利用微软的动态MSHTML对象模型实现一些浏览器的内部机制。
大家知道HTML文档是由标记语言构成,即俗称的Tag。微软的浏览器IE对于这些标记实现了一一对应的对象模型(objectmodel),由MSHTML.DLL封装。IE浏览器的实现也是由MSHTML.DLL来实现的。通过MSHTML.DLL我们可以直接操作对象模型的属性,方法。MSHTML的对象模型是基于COM组件对象的,对象的接口是基于Idispatch,操作MSHTML对象模型必须通过Idispatch接口。MSHTML中封装了许多这样的接口,例如,IhtmlAnchorElement接口对应与HTML文档中的超连接标记<A>,IHtmlHRElement接口对应<HR>标记,IhtmlTable接口对应<table>标记。其中最重要的是IhtmlDocument2接口,它对应Document组件。Document组件既相当于HTML文档。使用过Javascript的人对它应比较熟悉。
下面我们举例来讲解MSHTML的应用。在举例之前我先讲述一下Socket和HTTP协议。HTTP协议通过TCP连接服务器和Client,它工作在80端口。HTTP通过Client和Server之间的请求/应答机制进行通讯。HTTP消息分为Request和Response。每一种消息由开始行,消息头和消息体组成。形式如下:
generic-message = start-line
*message-header
CRLF
[ message-body ]
 
start-line的形式如下:
start-line = Request-Line | Status-Line
Request-Line为Client向Server发出的请求,形式如下:
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
Method 包括GET,POST等,在本例中我们只简单的使用GET向服务器发出请求。 
详细的HTTP协议请参考RFC2068。
在VC++中建立新的单文档EXE工程文件,为了使用MSHTML我们的视图类继承自ChtmlView。ChtmlView类封装了MSHTML接口。给工程中加入Socket类。
class CHttpSocket : public CSocket
{
………………
 
protected:
CWnd * m_pParentWnd;
}
其中m_pParentWnd指向我们的视图类,用于传送消息。在视图类中定义Socket。
class CSkhttpView : public CHtmlView
{
protected: // create from serialization only
CSkhttpView();
DECLARE_DYNCREATE(CSkhttpView)
…………….
protected:
CHttpSocket m_socket;
IHTMLDocument2 * phmDoc2;
……..
}
phmDoc2为IHTMLDocument2接口。初始化Socke,连接我们欲登录的站点,假设为

www.163.net
CSkhttpView::CSkhttpView()
{
// TODO: add construction code here
BOOL bRet=m_socket.Create(0,SOCK_STREAM,NULL); 
if(!bRet)
MessageBox("socket create error",NULL,MB_OK);
m_socket.SetParentWnd(this); 
if(!m_socket.Connect(www.163.net,80))
MessageBox(“socket connect error”,NULL,MB_OK);
}
下面我们取得IhtmlDocument2的接口。此接口的获得一般有两种方法。一是使用CoCreateInstance,然后调用QueryInterface。另一种是使用MSHTML控件对象的get_Document,在ChtmlView类中封装了这个接口。我们使用后一种。需要注意的是,我们需要在ChtmlView生成IhtmlDocument对象后才能获得它的接口。
void CSkhttpView::OnInitialUpdate() 
{
Navigate2(“about:blank”);
}
void CSkhttpView::OnDocumentComplete(LPCTSTR lpszURL)
{
LPDISPATCH lpdisp;
HRESULT hr;
lpdisp=GetHtmlDocument();
hr=lpdisp->QueryInterface(IID_IHTMLDocument2,(void **)&phmDoc2);
}
在ChtmlView初始化时调用Navigate2()产生空文档,文档产生后调用GetHtmlDocument获得一个Idispatch()接口,调用QueryInterface获得IHTMLDocument2接口。
void CSkhttpView::OnReceiveMessage(WPARAM wParam,LPARAM lParam)
{
HRESULT hr;
char buf[5000];
int inum;
IHTMLElement * pEleBody;
if(wParam==0)
{
inum=m_socket.Receive(buf,sizeof(buf),0);
buf[inum]=0;
_bstr_t bsrBody(buf);
hr=phmDoc2->get_body(&pEleBody);
hr=pEleBody->put_innerHTML(bsrBody); 
}

 
void CSkhttpView::OnControlSend() 
{
// TODO: Add your command handler code here
char buf[1000];
wsprintf(buf,"GET http://www.163.net HTTP/1.1/r/n/r/n");
int iRet=m_socket.Send(buf,lstrlen(buf),0);
if(iRet==SOCKET_ERROR)
MessageBox(“socket send error”,NULL,MB_OK);
}
我们向服务器发送HTTP协议的请求”GET http://www.163.net HTTP/1.1/r/n/r/n”,它取回指定URI地址的网页。服务器发出回应我们通过Socket接受。IhtmlDocument2内含许多对象借口,通过许多的put_,get_方法我们可以获得这些对象的属性,事件,方法。本例中我们获得body对象,它对应于HTML文挡中<body></body>对象。通过IhtmlDocument2的get_body()得到指定body对象的IHTMLElement接口,调用IHTMLElement接口的put_innerHTML()将接受到的内容放入Document中。此时在我们的视图中就会显示网页。
本文只是简略的介绍了一下MSHTML对象,它里面实际包含了许多的接口和函数,通过这些接口我们可以任意设计我们自己风格的浏览器。有兴趣的同志可以参阅MSDN文档。

JavaScript基础——浏览器对象模型(BOM)

简介 ECMAScript是JavaScript的核心,但如果要在Web中使用JavaScript,那么BOM(浏览器对象模型)则无疑才是真正的核心。BOM提供了很多对象,用于访问浏览器的功能,这些功...
  • Goskalrie
  • Goskalrie
  • 2016年06月20日 16:11
  • 2811

JAvaScript和DOM(文档对象模型)和BOM(浏览器对象模型)

DOM是针对XML但经过扩展用于HTML的应用程序编程接口DOM把整个页面映射成一个多层节点结构,HTML页面中的每一个组成部分都是某种类型的节点,这些节点也包含这不同类型的数据...
  • wang2963973852
  • wang2963973852
  • 2016年10月27日 13:58
  • 1311

JS DOM(文档对象模型)与BOM(浏览器对象模型)

在JS中,对DOM(Document Object Model)对象和BOM(Browser Object Model )对象的操作是非常重要的内容。DOM主要包括HTML文档的属性和方法,像对HTM...
  • qq_18895659
  • qq_18895659
  • 2016年06月18日 23:26
  • 795

JavaScript Window浏览器对象模型方法与属性汇总

Window 对象 所有浏览器都支持 window 对象。它表示浏览器窗口。 所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员。 全...
  • u012172536
  • u012172536
  • 2016年06月26日 00:53
  • 307

JS——浏览器对象模型BOM

什么是BOMBOM是browser object model的缩写,简称浏览器对象模型 BOM提供了独立于内容而与浏览器窗口进行交互的对象 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是...
  • culous
  • culous
  • 2016年09月17日 17:12
  • 533

浏览器对象模型BOM之window对象

1.BOM的概述     browser object modal :浏览器对象模型。     浏览器对象:window对象。     Window 对象会在 或 每次出现时被自动创建。 2....
  • CSDN_GIA
  • CSDN_GIA
  • 2016年11月27日 13:56
  • 474

解析ajax核心XMLHTTPRequest对象的创建与浏览器的兼容问题

MLHttpRequest 对象是AJAX功能的核心,要开发AJAX程序必须从了解XMLHttpRequest 对象开始。   了解XMLHttpRequest 对象就先从创建XMLHttpRequ...
  • chuck_kui
  • chuck_kui
  • 2017年02月09日 11:41
  • 1533

java对象创建(内存模型)过程详解

java对象创建详细过程步骤、jvm内存结构:声明对象引用和创建对象实体。类信息、对象引用、对象实体均在内存的不同区域。 内存结构 每一个java应用程序均会唯一的对应一个jvm实例,而这个jvm实...
  • Recall_Tomorrow
  • Recall_Tomorrow
  • 2017年04月09日 14:35
  • 764

基于事件的重叠IO模型

Windows socket重叠IO模型开发。        利用套接字重叠IO模型,应用程序能一次投递一个或多个IO请求,当系统完成IO操作后通知应用程序。该模型以win32异步IO机制为基...
  • rankun1
  • rankun1
  • 2015年12月19日 21:35
  • 1415

使用MSHTML解析HTML页面

最近在写一个爬虫项目,本来打算用C/C++来实现,在网上查找有关资料的时候发现了微软的这个MSHTML库,最后发现在解析动态页面的时候它的表现实在是太差:在项目中需要像浏览器那样,执行JavaScri...
  • lanuage
  • lanuage
  • 2017年06月01日 02:20
  • 2536
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用Socket和MSHTML对象模型创建自己的浏览器
举报原因:
原因补充:

(最多只允许输入30个字)