<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
用Socket和MSHTML对象模型创建自己的浏览器
中央财经大学管理信息系 薛 瑛 |
01-4-20 上午 11:15:22
|
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文档中的超连接标记,IHtmlHRElement接口对应 标记,IhtmlTable接口对应标记。其中最重要的是IhtmlDocument2接口,它对应Document组件。Document组件既相当于HTML文档。使用过Javascript的人对它应比较熟悉。
下面我们举例来讲解MSHTML的应用。在举例之前我先讲述一下Socket和HTTP协议。HTTP协议通过TCP连接服务器和Client,它工作在80端口。HTTP通过Client和Server之间的请求/应答机制进行通讯。HTTP消息分为Request和Response。每一种消息由开始行,消息头和消息体组成。形式如下: |
generic-message = 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向服务器发出请求。 |
在VC++中建立新的单文档EXE工程文件,为了使用MSHTML我们的视图类继承自ChtmlView。ChtmlView类封装了MSHTML接口。给工程中加入Socket类。 |
class CHttpSocket : public CSocket |
其中m_pParentWnd指向我们的视图类,用于传送消息。在视图类中定义Socket。 |
class CSkhttpView : public CHtmlView |
protected: // create from serialization only |
DECLARE_DYNCREATE(CSkhttpView) |
IHTMLDocument2 * phmDoc2; |
phmDoc2为IHTMLDocument2接口。初始化Socke,连接我们欲登录的站点,假设为www.163.net。 |
CSkhttpView::CSkhttpView() |
// TODO: add construction code here |
BOOL bRet=m_socket.Create(0,SOCK_STREAM,NULL); |
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) |
lpdisp=GetHtmlDocument(); |
hr=lpdisp->QueryInterface(IID_IHTMLDocument2,(void **)&phmDoc2); |
在ChtmlView初始化时调用Navigate2()产生空文档,文档产生后调用GetHtmlDocument获得一个Idispatch()接口,调用QueryInterface获得IHTMLDocument2接口。 |
void CSkhttpView::OnReceiveMessage(WPARAM wParam,LPARAM lParam) |
inum=m_socket.Receive(buf,sizeof(buf),0); |
hr=phmDoc2->get_body(&pEleBody); |
hr=pEleBody->put_innerHTML(bsrBody); |
void CSkhttpView::OnControlSend() |
// TODO: Add your command handler code here |
wsprintf(buf,"GET http://www.163.net HTTP/1.1/r/n/r/n"); |
int iRet=m_socket.Send(buf,lstrlen(buf),0); |
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文挡中对象。通过IhtmlDocument2的get_body()得到指定body对象的IHTMLElement接口,调用IHTMLElement接口的put_innerHTML()将接受到的内容放入Document中。此时在我们的视图中就会显示网页。 |
本文只是简略的介绍了一下MSHTML对象,它里面实际包含了许多的接口和函数,通过这些接口我们可以任意设计我们自己风格的浏览器。有兴趣的同志可以参阅MSDN文档。 |
<!-- Baidu Button BEGIN -->
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "1", "bdMiniList": false, "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script><!-- Baidu Button END --><!--192.168.100.35--><!-- Baidu Button BEGIN --><script type="text/javascript" id="bdshare_js" data="type=tools&uid=1536434"></script><script type="text/javascript" id="bdshell_js"></script><script type="text/javascript">
document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script><!-- Baidu Button END -->
主题推荐
对象
socket
http协议
应用程序
服务器
猜你在找
<script type="text/javascript">
var searchtitletags = ' 用Socket和MSHTML对象模型创建自己的浏览器' + ',' + '对象,socket,http协议,应用程序,服务器';
searchService({
index: 'blog',
query: searchtitletags,
from: 10,
size: 10,
appendTo: '#res-relatived',
url: 'recommend',
his: 2,
client: "blog_cf_enhance",
tmpl: '<dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="#{ url }" title="#{ title }" strategy="#{ strategy }">#{ title }</a></dd>'
});
</script>
<script type="text/javascript">
new Ad(4, 'ad_cen');
</script>
<script type="text/javascript">
var fileName = '2238717';
var commentscount = 0;
var islock = false
</script><script type="text/javascript" src="http://static.blog.csdn.net/scripts/comment.js"></script>
<script type="text/javascript">
new Ad(5, 'ad_bot');
</script>
<script type="text/javascript">
$(function ()
{
$("#ad_frm_0").height("90px");
setTimeout(function(){
$("#ad_frm_2").height("200px");
},1000);
if($("#comment_content").length>0)
{
$("#quick-reply").show();
$("#quick-reply").click(function(){
setEditorFocus();
});
}
var d_top = $('#d-top-a');
document.onscroll = function ()
{
var scrTop = (document.body.scrollTop || document.documentElement.scrollTop);
if (scrTop > 500)
{
d_top.show();
} else
{
d_top.hide();
}
}
$('#d-top-a').click(function ()
{
scrollTo(0, 0);
this.blur();
return false;
});
});
</script><style type="text/css">
.tag_list
{
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #D7CBC1;
color: #000000;
font-size: 12px;
line-height: 20px;
list-style: none outside none;
margin: 10px 2% 0 1%;
padding: 1px;
}
.tag_list h5
{
background: none repeat scroll 0 0 #E0DBD3;
color: #47381C;
font-size: 12px;
height: 24px;
line-height: 24px;
padding: 0 5px;
margin: 0;
}
.tag_list h5 a
{
color: #47381C;
}
.classify
{
margin: 10px 0;
padding: 4px 12px 8px;
}
.classify a
{
margin-right: 20px;
white-space: nowrap;
}
</style>
- 访问:1381347次
- 积分:83466分
- 排名:第4名
- 原创:7468篇
- 转载:0篇
- 译文:0篇
- 评论:81条
<script type="text/javascript">
$(function () {
$("#btnSubmit").click(function () {
search();
});
$("#frmSearch").submit(function () {
search();
return false;
});
function search()
{
var url = "http://so.csdn.net/so/search/s.do?q=" + encodeURIComponent($("#inputSearch").val()) + "&u=" + username + "&t=blog";
window.location.href = url;
}
});
</script>
<script type="text/javascript">
new Ad(12, 'ad_commend');
</script>
<script type="text/javascript" src="http://csdnimg.cn/rabbit/cnick/cnick.js"></script><script type="text/javascript" src="http://static.blog.csdn.net/scripts/newblog.min.js"></script><script type="text/javascript" src="http://medal.blog.csdn.net/showblogmedal.ashx?blogid=254649"></script><script type="text/javascript">
document.write('<script type="text/javascript" src="http://csdnimg.cn/pubfooter/js/publib_footer.js?' + Math.floor(new Date() / 120000).toString(36) + '="></' + 'script>');
</script><script type="text/javascript" src="http://passport.csdn.net/content/loginbox/login.js"></script><script type="text/javascript">document.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");</script><script type="text/javascript" src="http://www.csdn.net/ui/scripts/Csdn/counter.js"></script><script type="text/javascript" src="http://ad.csdn.net/scripts/ad-blog.js"></script><script type="text/javascript" src="http://zz.csdn.net/js/count.js"></script><script type="text/javascript">
$(function () {
function __get_code_toolbar(snippet_id) {
return $("<a href='https://code.csdn.net/snippets/"
+ snippet_id
+ "' target='_blank' title='在CODE上查看代码片' style='text-indent:0;'><img src='https://code.csdn.net/assets/CODE_ico.png' width=12 height=12 alt='在CODE上查看代码片' style='position:relative;top:1px;left:2px;'/></a>"
+ "<a href='https://code.csdn.net/snippets/"
+ snippet_id
+ "/fork' target='_blank' title='派生到我的代码片' style='text-indent:0;'><img src='https://code.csdn.net/assets/ico_fork.svg' width=12 height=12 alt='派生到我的代码片' style='position:relative;top:2px;left:2px;'/></a>");
}
$("[code_snippet_id]").each(function () {
__s_id = $(this).attr("code_snippet_id");
if (__s_id != null && __s_id != "" && __s_id != 0 && parseInt(__s_id) > 70020) {
__code_tool = __get_code_toolbar(__s_id);
$(this).prev().find(".tools").append(__code_tool);
}
});
});
</script><!--new top--><script id="csdn-toolbar-id" btnid="header_notice_num" wrapid="note1" count="5" subcount="5" type="text/javascript" src="http://static.csdn.net/public/common/toolbar/js/toolbar.js"></script><!--new top--> |
分享到:
相关推荐
C++ 使用MSHTML分析html ,对MSHTML分析html简单介绍
mshtml.dll文件 当遇到mshtml.dll文件缺失,破损,或者不兼容(如win 7 64位) 解决办法(本人win 7 64位): 1.将32位的mshtml.dll文件复制到SysWow64 文件夹下,将64位的mshtml.dll文件复制到SysWow32 文件夹下 2....
WebKit 是一个开源的浏览器引擎,与之相对应的引擎有Gecko(Mozilla Firefox 等使用)和Trident(也称MSHTML,IE 使用)。同时WebKit 也是苹果Mac OS X 系统引擎框架版本的名称.
Microsoft mshtml
mshtml.dll,引用到项目中即可使用。
mshtml,解决重新注册regsvr32 mshtml.dll 时显示没有找到输入
WebBrowser组件和MSHTML 在Delphi中的使用.doc
MSHTML.h把HTML页面中的元素封装成了IHTMLInputElement、IHTMLInputButtonElement、IHTMLInputTextElement、IHTMLTextAreaElement、...用webbrowser加上MSHTML.h可以实现把网页信息获取到浏览器组件中。
microsoft.mshtml.dll 7.0.3300.1
VC HTML操作教程。需要操作IE控件或其它功能,可以看看。
mshtml.dll 功能很强大 配合webbrowser 使用很好用的底层控件
mshtml操作html表格合并拆分 参数为当前单元格,单元格所在行 单元格所在表格
MSHTML最好用的HTML解析程序,最好用的HTMLParser,比HtmlAgilityPack好用一万倍
WebKit 是一个开源的浏览器引擎,与之相对应的引擎有Gecko(Mozilla Firefox 等使用),Trident(也称MSHTML,IE 使用)和EdgeHTML(也称Chakra,Edge和其他UWP浏览器使用)。同时WebKit 也是苹果Mac OS X 系统引擎...
数据采集 源码 mshtml 数据采集 源码 mshtml
Could not load file or assembly 'Microsoft.mshtml, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. 系统找不到指定的文件 IIS发布MVC程序 报Microsoft....
mshtml