|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
3 ~5 u6 |* }- W6 Z. C8 j) `) \% ^. I
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。. s4 f L. _% B9 e X* H% J6 F8 d
取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
5 y% f6 w. v5 e7 y7 d$ L <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
& n$ z! J* H5 L1 h; B/ W# n 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。" W- v5 e& h0 s* C u2 T
<3> 如果你的程序是用 ATL 写的 ActiveX 控件。
. x$ k) q1 _& b 那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
% p9 F# D+ I2 i- O" q) C! Q
% s9 M' S. O7 A6 [6 Z* hCComPtr < IOleContainer > spContainer;
9 t9 g j2 L8 b2 a& b' F1 I/ J9 \m_spClientSite->GetContainer( &spContainer );2 f) U# R$ f% C2 M6 g: o) x& k8 `
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
8 K+ N! m3 R1 E9 ~+ c! j1 Bif ( spDoc )5 @7 m2 w5 ?0 l; d5 w
{7 w7 m- n$ V+ d5 y5 e( J0 ?
// 已经得到了 IHTMLDocument2 的接口指针
A6 A# ?% E5 X8 z}
0 \' Y* J1 z/ @ C% M3 z. d. ~4 U `' I- ?
<4> 如果你的程序是用 MFC 写的 ActiveX 控件。
# {9 |' O0 s$ G/ t6 C 那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。5 L- E$ x) x9 C6 ^3 y
<5> IE 浏览器作为独立的进程正在运行。/ H1 i8 a: i5 B3 q2 @
每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:. y; f7 N0 Z) I
8 @6 k$ `' _" o+ \7 N" Z" j) d
#include < atlbase.h >
% ?9 x( Y" O: ^/ y#include < mshtml.h >
: H* H" f- f3 K! M' x5 b8 H
( S: {4 C' M3 Pvoid FindFromShell() / o7 ^- S+ Y% m
{3 B/ Y3 y9 y. t$ b+ ~
CComPtr< IShellWindows > spShellWin;
+ x+ c% ]* n5 f/ W1 j: t HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
# C* {6 b3 g3 U% [1 d if ( FAILED( hr ) ) return;
+ j+ m D& ^* V r S) \: p3 i" @# K8 A6 _2 D7 t
long nCount=0;
, i( [$ M' e& c+ S8 q( ]7 E spShellWin->get_Count(&nCount); // 取得浏览器实例个数2 R9 L: N) O2 u1 _. v; c8 \
. n% r, H% W0 g# K7 Y6 I for(long i=0; i<nCount; i++)! c* y7 i2 ?+ \9 q# T1 ?
{
3 g& }- z* W9 z5 y1 ~3 @( | CComPtr< IDispatch > spDisp;
8 a; r8 `8 }( ]; w! m. @* i hr=spShellWin->Item(CComVariant( i ), &spDisp );
* B' E6 ~3 @0 X, i) ~+ B8 D, k( L if ( FAILED( hr ) ) continue;
$ m" V3 ?' J( X( V, t( y6 D3 K1 p: I
CComQIPtr< IWebBrowser2 > spBrowser = spDisp;( J9 v0 H3 x- k: @' y4 ?
if ( !spBrowser ) continue;- p2 ~, ?2 ?4 {1 d
3 |! ?3 B8 M C" r0 ~/ W _
spDisp.Release();$ ^3 T& T$ I. B5 L8 U6 b* K
hr = spBrowser->get_Document( &spDisp );( h! Q' o( y, [' M! s
if ( FAILED ( hr ) ) continue;% ?! E( @5 k, L7 s' `1 a7 m
/ k; x" d: V6 O4 G( z6 ?
CComQIPtr< IHTMLDocument2 > spDoc = spDisp;& C7 ~; r* `9 h: s) W9 Y
if ( !spDoc ) continue;0 [ c+ W3 ~% S0 C3 j% L' E! V9 Z
1 M/ J8 R$ v K0 D' S/ t6 t! R
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针6 d s9 V7 r7 }; N
} Q& x+ Q% W) h7 T) q. }
}
6 l9 R$ z7 k9 N1 J& L: ^( M* C
9 N0 O5 X- Z2 @# F; \% B, B, X <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: ' O( j+ E. F6 h, Q4 Y$ b
5 j; {3 V5 ?! ^2 H% K/ i3 \
+ q2 y0 u; C! [, K! x# W0 t1 y
#include < atlbase.h >
, O8 j( x+ x* ?1 o#include < mshtml.h >
3 s" G. Z1 I/ e8 q0 e& N#include < oleacc.h >
8 ]( _* M% E7 q/ K' G#pragma comment ( lib, "oleacc" )
& T2 v j$ u* K$ @1 v' M {( h; F! x0 B U" [3 i7 u
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
2 U; n% b/ q; W2 k3 G/ Q, _8 U{
6 g; _) H4 G. R9 R( H6 y: R TCHAR szClassName[100];
& n* s- V; w' h" W" j7 A- y8 Z7 ~- ?5 y1 F
::GetClassName( hwnd, &szClassName, sizeof(szClassName) );
1 t, }- F+ ?3 K3 H if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )# z6 |4 m- S. Q% X
{
/ d9 T5 d3 @ ~. j4 ~0 l *(HWND*)lParam = hwnd;
5 I0 s$ C7 k( G) [6 O2 O4 t return FALSE; // 找到第一个 IE 控件的子窗口就停止- ]5 f O! |9 l- u% }, w
}! e; a; S4 K1 n0 W& w; U- S
else return TRUE; // 继续枚举子窗口
& L2 m, y* ^. U; D0 w};
8 _# N/ g: J% ^
5 I6 Y) K5 k% w* }5 H& b5 \1 u jvoid FindFromHwnd(HWND hWnd) ( a: Z, S; j" `8 u
{
+ w4 W0 L" h7 o$ V HWND hWndChild=NULL;1 n9 @9 A, x$ L& k+ y! S2 X0 T, O
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
% g9 q0 `( z9 ~5 t if(NULL == hWndChild) return;& g; N8 T$ m2 Y* }) H: j5 n2 V9 B
/ r' N, L3 I5 z6 | UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );! M( X( M1 X# I5 a2 }; T
LRESULT lRes;3 m3 p& ? k& D2 a
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
- i) J* ]2 j" N, G3 W+ Y& h" ~
# K0 c. B* k/ Q8 Z: ^& G2 X. X- X CComPtr < IHTMLDocument2 > spDoc;
6 y- f- N! `- |' Z HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );0 Y5 I, u" a w* } i1 ?: n
if ( FAILED ( hr ) ) return;) X7 W1 U. I8 d8 z3 W
) H* s* ~9 p; {9 v" O0 r0 ?: l // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针! _+ k9 {) F, ~- Q6 z
} |
|