|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
" k! ?/ G) j7 T( S3 N2 ~" O7 B7 V$ o0 } d3 s
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。3 h4 ^2 H% B+ L- d R2 }: [
取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。2 Y, _* C4 j0 }$ V
<2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
4 b }7 Q, {, E" z 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。+ C7 }8 u% R2 R" n# a
<3> 如果你的程序是用 ATL 写的 ActiveX 控件。2 ?$ u) ~* a. J& G1 L
那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
, J( k- \ a6 ?. M) K( b3 c! n
# c) [* s' x0 h) K; eCComPtr < IOleContainer > spContainer;
( e0 T9 d) ~: U0 t* O% A- ^0 Mm_spClientSite->GetContainer( &spContainer );# a- o' C. O0 h1 x& J
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;* I" O/ V' U5 D/ c: J
if ( spDoc )$ O0 l5 N! I' f# J7 W
{
) Z# ?. {/ ~6 y1 q8 b5 ] // 已经得到了 IHTMLDocument2 的接口指针
. d/ J1 y6 B6 q9 Q9 _" x& m! W}
& |& Q" z9 a2 x% A6 O
6 {3 S" P. R3 _7 h5 Z4 v" F <4> 如果你的程序是用 MFC 写的 ActiveX 控件。) B Y X0 k# \$ C5 T
那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
2 b6 @' s" h$ S4 n' \ <5> IE 浏览器作为独立的进程正在运行。6 {; ~- b: N& {4 ?0 b9 z
每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
! [" i1 {5 X, E& d0 b' p4 s$ s5 B3 ]% h% I
#include < atlbase.h >
' r. @( ?% e0 p H1 `: O$ w' f#include < mshtml.h >& ]# V9 \) B# _
; r- g9 ?$ r) o0 l/ C
void FindFromShell() }) _ z- @8 U# [" C2 K6 J: C( z
{8 a9 L( M3 Q5 O3 v! f, l
CComPtr< IShellWindows > spShellWin;
- L7 j1 C$ }( @9 R4 B HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
; `4 e/ N. s% G# y5 V if ( FAILED( hr ) ) return;) u/ _1 W& g. n( R0 {
* v y3 M- Q N& Q3 Z; d
long nCount=0;
4 J" q8 @4 s7 J* ]: p) U; y spShellWin->get_Count(&nCount); // 取得浏览器实例个数4 a, u) V+ i: ^! [( P" Z# c
# h6 F+ Y+ N5 k* | for(long i=0; i<nCount; i++)
4 ]" R$ ?0 D& J {
! _& h: N% M' D0 j& U9 s9 H4 e CComPtr< IDispatch > spDisp;
" K; W6 Y' s/ `& x4 M9 C- Q hr=spShellWin->Item(CComVariant( i ), &spDisp );4 N! v5 I/ |2 n2 U2 u- V6 m: }
if ( FAILED( hr ) ) continue;
* `) n7 h( y; a) H! L1 R7 o8 x
+ R; u$ T' X S9 O3 x8 F# z8 V& m, o CComQIPtr< IWebBrowser2 > spBrowser = spDisp;- t9 `2 c+ P3 _+ |. W7 f& U2 `. V
if ( !spBrowser ) continue;
8 }* L0 N( Z& R% Q# j# V7 E- a2 t
spDisp.Release();2 q& q7 P$ B. g) c1 z
hr = spBrowser->get_Document( &spDisp );6 J( f9 j$ V6 z# D% e
if ( FAILED ( hr ) ) continue;" _/ i, p( O+ M5 m& Z% w: I
9 [6 v( m% |. u1 _7 L, C# o" M CComQIPtr< IHTMLDocument2 > spDoc = spDisp;* I" W4 [3 ]8 y: K: _
if ( !spDoc ) continue;8 f# K, W B) @1 [# _0 e
& ?9 u8 b' b. D // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 e* E& ]4 C, E7 @: {2 E
}
" K* u- q2 Y' `}
, ]( F% @# s& Q. S/ K) A! y, c c0 e6 k; W5 o3 w
<6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
; d1 j/ q) L, n; t! Y# F. Z" P# `& k( o/ b" `) l4 u; x
" o. C0 O& o) s% Y
#include < atlbase.h >
6 K7 H# }) j1 S9 N9 L/ t#include < mshtml.h >
! i6 \- E# J5 v% v- B* H#include < oleacc.h >; K/ b& g" N5 z( z1 @
#pragma comment ( lib, "oleacc" )) H6 \# ^! E. n: Y; z
" y# ^ ?' q; j: {0 M" Z6 {$ z0 j
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
1 n/ i/ g4 Q0 a0 j% S; e" ?{+ S2 ?; j! Z+ G/ [/ _" } m8 B; n
TCHAR szClassName[100];5 g4 s& y/ Y' G2 R2 E( s$ g R8 O
: _( U3 Q5 E9 R; t" ]& q5 @* Y3 W ::GetClassName( hwnd, &szClassName, sizeof(szClassName) );- E: l1 w( i; a# ]! q
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )3 \2 L( a1 U- U: x9 J! J' W0 h4 u
{: ~/ q0 j: l5 v3 F8 Z" ^. Q; D
*(HWND*)lParam = hwnd;
$ K$ Y/ b( ^; K' \) u return FALSE; // 找到第一个 IE 控件的子窗口就停止/ r) U8 S! J& d3 M8 H4 l6 ?6 V
}% S2 w/ G4 V8 |2 x
else return TRUE; // 继续枚举子窗口3 Y. d) v+ [* o9 s* {, J' X
};, r( r, ?, L [- T2 k, {
# H3 Y$ B! c) [: Y1 g5 |5 Ovoid FindFromHwnd(HWND hWnd)
* e, t7 B, C( L& O' [' M7 {{ D2 C( _3 m3 H6 e' U7 E6 K
HWND hWndChild=NULL;
6 J0 ]$ _- `# q8 P$ I; h$ P ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
) d2 q& n% R! e$ j if(NULL == hWndChild) return;
- ?( G: \3 W* [6 [$ b2 w) K A
- K* k$ i; g2 C, S- L, L UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
' i) y1 L. e' s! D LRESULT lRes;
. l: ?* M. j. f! s( J7 O ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );6 X, S9 L* i% R& M% ]7 _' @
4 a& `6 W4 o& T8 A* _/ F2 z/ P5 f! C" T CComPtr < IHTMLDocument2 > spDoc;
2 o9 n. N: w8 n3 K' s HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
/ l$ ]; R3 N Y- K% O" W if ( FAILED ( hr ) ) return;9 h& @/ ^% S6 O% K
) \2 v+ X8 }1 N. s // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针& ?& B2 c. E* |. g" h Q) b
} |
|