CHtmlView

<!-- /* Font Definitions */ @font-face {font-family:"MS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-alt:"MS Mincho"; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:SimSun; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:宋体; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:Century; panose-1:2 4 6 3 5 7 5 2 3 3; mso-font-alt:"Times New Roman"; mso-font-charset:0; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:3 0 0 0 1 0;} @font-face {font-family:"/@MS 明朝"; panose-1:2 2 6 9 4 2 5 8 3 4; mso-font-charset:128; mso-generic-font-family:roman; mso-font-pitch:fixed; mso-font-signature:-1610612033 1757936891 16 0 131231 0;} @font-face {font-family:"/@SimSun"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0mm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:Century; mso-fareast-font-family:"MS 明朝"; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:99.25pt 30.0mm 30.0mm 30.0mm; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:18.0pt;} div.Section1 {page:Section1;} -->

要包含的 文件

#include "stdafx.h"

#import <mshtml.tlb> // Internet Explorer 5  
#import <shdocvw.dll>  
#include "Shlwapi.h"  
#pragma comment(lib,"Shlwapi.lib")
//--------------------
#include <mshtml.h>
#include <atlbase.h>
#include <oleacc.h>
//---------------------

下面是代 , 我是用 webbrowser 控件做和 浏览 ,CHTMLVIEW 其他也是可以的

实现 的功能是根据内容插入表 , 保存也是一 的道理 .
会乱 , 所以没加上 , 如果看不懂 , 可以看下面我从我博客上 制来的一篇文章
void CHelpDlg::OnButtonSubmit() 
{
// TODO: Add your control notification handler code here
HWND hWnd = AfxGetMainWnd()->m_hWnd;

CoInitialize(NULL); //
初始化 COM
SHDocVw::IShellWindowsPtr m_spSHWinds;  
if(m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) == S_OK)  
{  
IDispatchPtr spDisp;  
long nCount = m_spSHWinds->GetCount();  
for(long i =0;i<nCount;i++)  
{  
_variant_t va(i, VT_I4);  
spDisp = m_spSHWinds->Item(va);  
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);  
if (spBrowser != NULL)  
{  

IDispatchPtr spDisp;  
if(spBrowser->get_Document(&spDisp) == S_OK && spDisp!= 0 )  
{  
MSHTML::IHTMLDocument2Ptr spHtmlDocument(spDisp);  
MSHTML::IHTMLElementPtr spHtmlElement;  
if(spHtmlDocument==NULL)  
continue;  

spHtmlDocument->get_body(&spHtmlElement);  
if(spHtmlDocument==NULL)  
continue;  
HRESULT hr;  
MSHTML::IHTMLElementCollection* pColl=NULL;  
hr=spHtmlDocument->get_all(&pColl);  
if(pColl!=NULL&&SUCCEEDED(hr))  
{  
long lcount = 0;  
pColl->get_length(&lcount);  
for(int i=0;i<lcount;i++)  
{  
_variant_t index;  
index.vt=VT_I4;  
index.intVal=i;  
IDispatchPtr disp;  
disp=pColl->item(index,index);  
if(disp==NULL)  
hr=E_FAIL;  
else  
{  
MSHTML::IHTMLInputElementPtr pInput(disp);  
if(pInput)  
{  
BSTR bstrtype;  
pInput->get_type(&bstrtype);  
//printf(_bstr_t(bstrtype));
if(StrCmpW(bstrtype,L"text")==0)  
{
MSHTML::IHTMLElementPtr e(pInput);//
以下是 于表 , 上面已 可以得到整个网 的内容了 , 把下面的表 部份改成你自已要 实现 的功能就可以了
// }
}  
SysFreeString(bstrtype);  
}  
}  

}  
pColl->Release();  
}  
}  

}  
}  

}  
else  
{  
printf("Shell Windows interface is not avilable/n"); 
}  
CoUninitialize(); 
}

 

下面是


实现 IE 浏览 器交互的几 方法的介
  

---- 1
.引言

----
如何 实现对 IE 浏览 器中 象的操作是一个很有 实际 义问题 ,通 IE 定的 DLL 可以 记录 IE 浏览过 的网 序,分析用 的使用行 和模式。我 可以 的内容 过滤 和翻 ,可以自 填写网 常需要用 填写的 Form 内容等等 , 所有的例子代 都是通 VC 来表示的,采用的原理是通 IE 象的接口的交互来 实现对 IE 访问 实际 上是采用 COM 的技 ,我 知道 COM 是和 言无 的一 象交互的模式,所以 实际 上我 下面所描述 的内容都可以用其他的 言来 实现 ,比如 VB DELPHI C++ Builder 等等。

---- 2
IE 例遍 历实现

----
首先我 来看系 是如何知道当前有多少个 IE 例在运行。

----
知道在 Windows 体系 构下,一个 用程序可以通 操作系 的运行 象表来和 用的 行交互。但是 IE 当前的 实现 机制是不在运行 象表中 行注册,所以需要采用其他的方法。我 知道可以通 ShellWindows 集合来代表属于 shell 的当前打 的窗口的集合,而 IE 就是属于 shell 的一个 用程序。

----
下面我 描述一下用 VC 实现对 当前 IE 例的 行遍 的方法。 IShellWindows 于系 shell 的一个接口,我 可以定 一个如下的接口 量:

SHDocVw::IShellWindowsPtr m_spSHWinds;
然后 量的 例:
m_spSHWinds.CreateInstance
(__uuidof(SHDocVw::ShellWindows));
IShellWindows 接口的方法 GetCount
可以得到当前 例的数目:
long nCount = m_spSHWinds- >GetCount();
IShellWindows 接口的方法 Item
可以得到 一个
IDispatchPtr spDisp;
_variant_t va(i, VT_I4);
spDisp = m_spSHWinds->Item(va);
然后我 可以判断 象是不是
属于 IE 浏览 象,通 下面的 实现
SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
assert(spBrowser !=
NULL)

----
在得到了 IE 浏览 象以后,我 可以 IWebBrowser2Ptr 接口的方法来得到当前的文档 象的指 MSHTML::IHTMLDocument2Ptr spDoc(spBrowser->GetDocument());

----
然后我 就可以通 过这 个接口 对这 个文档 行操作,比如通 Gettitle 得到文档的 标题

---- 浏览 候,一般 会同 时开 很多 IE 例,如果 面都是很好的 ,我 可能想保存在硬 上, 这样 ,我 需要 对每 一个 行保存,而如果 采用上面的 原理,我 可以得到 一个 IE 例及其网 页对 象的接口, 这样 就可以通 一个 简单 的程序来批量的保存当前的所有打 的网 。采用上面介 方法 实现 当前 IE 例的遍 ,但是我 希望得到 一个 IE 例所 生的事件, 就需要通 DLL 的机制来 实现

---- 3
.和 IE 定的 DLL 实现

----
一下如何建立和 IE 定的 DLL 实现 程。 了和 IE 的运行 定,我 需要建立一个能 一个 IE 定的 DLL IE 的启 动过 程是 这样 的,当 一个 IE 例启 候,它都会在注册表中去 个的一个 CLSID ,具体的注册表的 位置

HKEY_LOCALL_MACHINE/SOFTWARE/Microsoft/Windows
/CurrentVersion/Explorer/Browser Helper Objects

----
当在 位置下存在 CLSIDs 候, IE 会通 使用 CoCreateInstance() 方法来 建列在 该键 位置下的 一个 象的 例。 注意 象的 CLSIDs 用子 而非名字 的形式表 ,比如 {DD41D66E-CE4F-11D2-8DA9-00A0249EABF4} 就是一个有效的子 。我 使用 DLL 的形式而非 EXE 的形式的原因是因 DLL IE 例运行在同一个 程空 里面。 一个 这种 形式的 DLL 须实现 接口 IObjectWithSite ,其中方法 SetSite 实现 。通 过这 个方法,我 自己的 DLL 就可以得到一个指向 IE COM 象的 IUnknown 的指 实际 上通 过这 个指 就可以通 COM 象中的方法 QueryInterface 来遍 所有可以得到的接口, COM 的基本的机制。当然我 需要的只是 IWebBrowser2 个接口。

----
实际 上我 建立的是一个 COM 象, DLL 只不 COM 象的一 形式。我 建立的 COM 象需要建立和 实现 的方法有:

----1
IOleObjectWithSite 接口的方法 SetSite 须实现 实际 IE 例通 过这 个方法向我 COM 传递 一个接口的指 。假 有一个接口指 量,不妨 设为

----CComQIPtr< IWebBrowser2, &IID_IWebBrowser2 > m_myWebBrowser2;

----
就可以在方法 SetSite 中把 传进 来的接口指 针赋给 m_myWebBrowser2 2 在我 得到了指向 IE COM 象的接口后,我 需要把自己的 DLL IE 例所 生的事件相 关连 , 实现这 个目的,需要介 两个接口:

----
1 IConnectionPointContainer 里使用 个接口的目的是用来根据它得到的 IID 来建立和 DLL 的一个特定的 接。比如我 可以 行如下的定

CComQIPtr< IConnectionPointContainer,
&IID_IConnectionPointContainer > 
spCPContainer(m_myWebBrowser2);

----
然后,我 需要把所有 IE 生的事件和我 DLL 行通 ,可以使用 IConnectPoint

-- --
2 IConnectPoint 。通 过这 个接口,客 可以 对连 接的 始或者是 止一个 advisory IConnectPoint 有两个主要的方 法,一个 Advice ,另一个 Unadvise 于我 用来 Advise 是用来在 一个 IE 生的事件和 DLL 建立一个通道。而 Unadvise 就是用来 止以前用 Advise 建立的通知 系。比如我 可以定 IConnectPoint 接口如下: CComPtr< IConnectionPoint > spConnectionPoint;

----
然后,我 要使所有在 IE 例中 生的事件和我 DLL ,可以使用 如下的方法:

hr = spCPContainer->FindConnectionPoint(
DIID_DWebBrowserEvents2, &spConnectionPoint);

----
然后我 IConnectPoint 接口的方法 Advice 使 IE 有一个新的事件 生的 候,都能 够让 DLL 知道。可以用如下的 实现

hr = spConnectionPoint- >Advise(
(IDispatch*)this, &m_dwIDCode);

----
在把 IE 例中的事件和我 DLL 建立 系以后,我 可以通 IDispatch 接口的 Invoke() 方法来 理所有的 IE 的事件。

-- --3
IDispatch 接口的 Invoke() 方法。 IDispatch 是从 IUnknown 承的一个接口的 型,通 COM 接口提供的任何服 都可以通 IDispatch 接口来 实现 IDispatch::Invoke 的工作方式同 vtbl 幕后的工作方式是 似的, Invoke 实现 按索引来 访问 的函数,我 可以 Invoke 方法 动态 的定制以提供不同的服 Invoke 方法的表示如下:

STDMETHOD(Invoke)(DISPID dispidMember,REFIID
riid, LCID lcid, WORD wFlags,
DISPPARAMS * pdispparams, VARIANT * pvarResult,
EXCEPINFO * pexcepinfo, UINT * puArgErr);

-- --
其中, DISPID 是一个 整数,它 标识 的是一个函数。 IDispatch 的某一个特定的 实现 DISPID 都是唯一的。 IDispatch 一个 实现 都有其自己的 IID, dispidMemeber 实际 上是可以 认为 是和 IE 例所 生的 一个事件相 的方法,比如: DISPID_BEFORENAVIGATE2 DISPID_NAVIGATECOMPLETE2 等等。 个方法中另外一个比 重要的参数是 DISPPARAMS ,它的 构如下:

typedef struct tagDISPPARAMS
{
VARIANTARG* rgvarg;
//VARIANTARG
是同 VARAIANT 相同的,可以在
//OAIDL.IDL
中找到。所以 实际 rgvarg 是一个参数数
//

DISPID* rgdispidNameArgs; //
命名参数的 DISPID
unsigned int cArgs; //
表示数 中元素的个数
unsigned int CnameArgs; //
命名元素的个数
}DISPPARAMS

-- --
要注意的是 一个参数的 型都是 VARIANTARG ,所以在 IE 和我 DLL 可以 传递 的参数 型的数目是有限的。只有那些能 被放到 VARIANTARG 构中的 型才可以通 过调 度接口 传递 。比如 于事件 DISPID_NAVIGATECOMPLETE2 :第一个参数表示 IE 访问 URL 型是 VT_BYREF|VT_VARIANT 。注意 DISPID_NAVIGATECOMPLETE2 DISPID VC 中被定 ,我 可以直接 行使 用。如上 述,我 在方法 Invoke 中可以得到所有 IE 例所 生的事件 ,我 可以把 些数据放到文件中 行事后的分析,也可以放到一个列表框中 实时 示。

---- 4
.微 HTML 文档 象模型和 用分析

----
下面我 来看如何得到网 文档的接口:网 文档的接口 IHTMLDocument2 ,可以通 过调 IE COM 象的 get_Document 方法来得到网 的接口。使用如下的 句:

hr = m_spWebBrowser2- >get_Document(&spDisp);
CComQIPtr< IHTMLDocument2,
&IID_IHTMLDocument2 > spHTML;
spHTML = spDisp;

----
这样 就得到了网 页对 象的接口,然后我 就可以 页进 行分析,比如通 IHTMLDocument2 提供的方法 get_URL 可以得到和 URL 的地址 ,通 get_forms 方法可以 中所有的 Form 象的集合。 实际 W3C 组织 制定了一个 DOM Document Objec Model 准,当然 准不 仅仅 针对 HTML ,同 时还 针对 XML 制定的。 W3C 组织 只是定 了网 页对 象的接口,不同的公司可以采用不同的 言和 方法 行具体的 实现 。按照 W3C 组织 的网 页对 象被 认为 动态 的,即用 可以 动态 页对 象里面所包含的 一个 行操作。 里的 象可以是指一个 入框,也可以是 象和声音等 象。同 按照 W3C 的正式文档的 明,网 页对 象是可以 动态 增加和 除的。事 上,很少有厂商 实现 DOM 的所有功能。 软对 页对 象的定 也基本上是按照 实现 的。但是当前的接口 不支持 动态 的增加和 除元素,但是可以 中的基本元素 行属性的修改。比如 IHTMLElementCollection 表示网 中一些基本的元素的集合, IHTMLElement 表示网 中的一个基本的元素。而象 IHTMLOptionElement 接口就表示一个特定的元素 Option 。基本的元素都有 setAttribute geAttribute 方法来 置和得到元素的名称和

----
较为 的一个 用是我 分析网 中是否有需要填写的 Forms ,如果 个网址的 Forms 以前已 填写 而且数据我 保存下来的 ,我 就可以 把数据自 放到和 URL 下的 Forms 的相 的位置中去。另外,我 可以 总结 上需要填写的 Form 的数据 ,先 对这 些数据 项进 赋值 ,以后碰到有相 同的数据 候就自 把我 们赋值 的内容填写 去。 实际 Form 象, Form 中包含的元素,比如 INPUT OPTION SELECT 型的 入元素都是 象。

----
另外一个可以想到的 用是自 动对 中的文本 行翻 ,因 可以修改网 中任何 象的属性,所以我 可以把里面不属于本国 言的部分自 成本国 言,当然真正的 实现还 要靠自然 言理解方面技 的突破,但是 IE 浏览 器的接口和 象的形式使我 灵活的控制整个 IE ,无 是从事件 是到网 页对 象。

---- 5
.小

----
上面我 分析了如何得到所有 IE 例,同 了和 IE 例相捆 DLL 详细 实现 机制,同 时对 象化 行了分析。并且介 了几个相 实现 的方法及存在的技 术问题 IE 是一个 件化的以 COM 浏览 器,它具有 大的功能,同 时为应 开发 者留下了广 的空 ,当然它也存在体 大,速度相 慢的缺点。但是它的体系 构代表了微 新的技 ,因此具有 大的生命力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值