|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。9 M }; N9 B6 q" R; ~4 U9 w
4 |; D' x5 V: J/ @/ J* U# t3 y <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
. N$ M, o% @# D3 F8 t2 U5 y7 U% Q 取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。2 n- |9 W" G) R; N3 y7 z1 F
<2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
0 v3 Z) m6 ^! S( p ] M. o2 h 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
0 G1 @; o: Y* ?. u5 P% h# w$ k+ P <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
0 u/ A: }' s. q8 h6 ]' ^ 那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: " H& W4 r: D0 J+ g% `2 `( C$ b& |
3 a% W/ R5 c8 x) ]0 F. \# y
CComPtr < IOleContainer > spContainer;
6 q+ A, D1 p0 Q0 Im_spClientSite->GetContainer( &spContainer );0 J3 P+ e5 Z+ H0 {7 k$ z. _
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
% e( O" Z, X+ d( O# `6 z% ~, u& jif ( spDoc ). k' b& y( q" [( `% s
{
/ m) L7 w- Y1 S" N" L3 J // 已经得到了 IHTMLDocument2 的接口指针
5 p, L0 C' a) v, e4 q$ N; `" {}, v% l# w* L8 x+ H- x' H
; f' X, x5 R% h9 z <4> 如果你的程序是用 MFC 写的 ActiveX 控件。" ?9 I& z# g' ~" Z2 {' b( W
那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& c% E, j! E) j8 K# D: m <5> IE 浏览器作为独立的进程正在运行。7 K. @/ F: u" I! C
每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
' N) p1 ^. g5 T0 j$ x! I+ n1 i* G; J* |" F( D! W$ k2 J
#include < atlbase.h >' l3 s. x# K, @: C
#include < mshtml.h >
) d Y, d6 f9 B& d' F# G# a6 M
7 q0 B: p( s. g% ]- ovoid FindFromShell() 7 D H, @( k/ H
{& l1 |3 k: P0 q( F- w
CComPtr< IShellWindows > spShellWin;
5 z# d( e+ E$ r+ H, q8 a4 [4 t HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
2 Z9 w1 i, y8 Z# I* [; x. ? if ( FAILED( hr ) ) return;
/ S: E) t! i1 V6 }4 Y
& q" T0 S* Q9 ^4 g$ I long nCount=0;
% T, D% T" Y3 C# V spShellWin->get_Count(&nCount); // 取得浏览器实例个数
! {* L2 T6 u% ?/ l7 h C& o+ m
: h9 y% q; v, k0 |4 n. Y* h/ e0 d for(long i=0; i<nCount; i++)
1 T: ~" r8 {2 ~, [; |1 U/ @9 w3 I {. e j, m; q/ A% W
CComPtr< IDispatch > spDisp;! q0 F: l m3 K, N' w, i
hr=spShellWin->Item(CComVariant( i ), &spDisp );( Z) F- _) D4 ^
if ( FAILED( hr ) ) continue;
7 r% D: ^8 ? ~& a, G+ X. J9 e# A4 B0 j/ }! \
CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
* i7 I% r2 i& o3 o* [ f if ( !spBrowser ) continue;. ~6 }! J+ k; m6 _* K W. M( ]" Q
3 l/ N6 [# ~3 x# B7 w! B spDisp.Release();9 |( B5 c+ d4 @ e7 q! w/ @$ _
hr = spBrowser->get_Document( &spDisp );% \$ Y- ?" w6 Y8 D
if ( FAILED ( hr ) ) continue;
8 [% ?/ w1 c1 c; h7 _
: q$ S* W% w4 [4 T% C9 J6 w; e n CComQIPtr< IHTMLDocument2 > spDoc = spDisp;1 S/ |9 L: Q, W/ k
if ( !spDoc ) continue;
# h; F# e- k2 p5 v9 A7 \: j) Y# e; g4 D8 }: N0 ?4 i h
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
* n8 C, _! u' i3 q' A% `) t1 [3 h ~1 g }
) H5 O0 I" R) |" k" O}- \) X* x5 S p6 M4 Y
; o3 F) P9 }( @- r9 P; L% Y" Y0 I <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 1 S1 q/ `2 m; |9 v0 g
( ^. F6 {. J/ ?& v- M0 A+ r4 F
i {6 A5 b* `0 q2 E0 R& K2 u3 K#include < atlbase.h >
3 m" \& H U. t, A' L. _#include < mshtml.h >
: F+ A. m; E7 H. d4 [#include < oleacc.h >- B1 p' i; D8 c4 G
#pragma comment ( lib, "oleacc" )
) A/ U$ D- W- c3 W% F8 R
# i/ ~* _8 j2 E8 O- lBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)+ V ?# O" E" p
{
7 a( R" w7 Y& g$ K TCHAR szClassName[100];- K1 R6 C0 M; |( Y4 D0 C
# h+ a ?6 ~. Z" u" \
::GetClassName( hwnd, &szClassName, sizeof(szClassName) ); L/ K/ {1 c1 I d5 Z
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )8 }+ p! N6 B& z6 i$ H( x
{5 n, u7 L( C) p( A
*(HWND*)lParam = hwnd;
' N8 N4 H3 v6 s7 K. C return FALSE; // 找到第一个 IE 控件的子窗口就停止
7 K9 o* _6 {' ^1 N$ B" R }
9 {" `( j% w5 F0 m' _7 r else return TRUE; // 继续枚举子窗口7 S* a; e+ m6 U9 ]# I
};
8 Q" _4 W: R8 j$ H( c8 u" z& T5 p( _7 p/ t7 E
void FindFromHwnd(HWND hWnd) ( o% I% o) w( ]
{& u+ W$ \& O; C- }
HWND hWndChild=NULL;
. `, x! m6 q. g. O% {2 Q ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
! u8 T7 g( B2 X3 G' P Y5 ?7 V if(NULL == hWndChild) return;
1 Q: r7 @) z% x7 w3 m, [; d; \+ s; D6 l7 F8 [( x
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
. \: ` Q" ^0 H( N$ \0 A! B4 J LRESULT lRes;5 _* l _) t# v* W" M; M
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );# h5 J+ o& ], Q8 s( q
7 O9 E5 r. O, p8 R8 A
CComPtr < IHTMLDocument2 > spDoc;
; A2 |6 g$ \, F: v! f0 U( u HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc ); U1 O, m8 T& d" C0 K }
if ( FAILED ( hr ) ) return;
3 W( q6 l1 j& g+ x1 q3 L/ W% h( [# b" I% ?, b
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
" g0 Y4 x4 w' ^2 g% G8 ^/ a} |
|