|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
' _( I8 V! E" V8 y A7 u+ c# r$ G7 E
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。+ [! j& D! ~: D% f; l. O+ m$ x; Z
取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
' X) t! ~8 m3 k5 j+ R5 S: H# R1 j <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
& A8 [ r- I1 S' @4 ~' _1 E 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
8 j" n* u) q! y6 Q& @& c0 j <3> 如果你的程序是用 ATL 写的 ActiveX 控件。( f# e: g4 f1 V& j Q, N# H
那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
! l- {1 X3 ?8 K+ N* j, @9 B
# ?) i; J4 @( L$ Y9 N9 nCComPtr < IOleContainer > spContainer;
7 A( \ ^. h8 a/ d5 m! b& vm_spClientSite->GetContainer( &spContainer );: Z8 H/ p- I: K5 u N- b9 n, ~
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
/ i$ Z) C4 S" i$ y6 ]: xif ( spDoc )
% w( p1 w% c( Z3 b5 L{
' B. W8 |" {1 C- i; I' z' j4 f // 已经得到了 IHTMLDocument2 的接口指针
- v4 |1 i' B1 N}: ~" q/ s& L( V; p. D2 P: u
& D0 H8 A" F3 m5 j' y: s <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
+ L! ?% r1 ~3 }9 ]/ q1 D I0 Q 那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。: N( f: s1 f4 }
<5> IE 浏览器作为独立的进程正在运行。
- e" B6 p# t+ C3 R* P$ k" g! e 每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
; ^+ i% A, R; x% `0 X7 C+ E, l. t `! l( _; @& i2 ~
#include < atlbase.h >
7 j$ M9 R. Q# a. l2 T* S& _* }1 [#include < mshtml.h >3 k% W, s/ Q4 S* h
, ?0 u" y; @- D% C. E- _, ]. V
void FindFromShell() & f( c1 T( j: z) E
{
I# K6 V8 h7 u% b+ R CComPtr< IShellWindows > spShellWin;
! V& A0 {, v/ W+ l- m' b/ ? V& d/ ? HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );- t7 [) B' n: G$ } l3 G+ u, W* N2 o
if ( FAILED( hr ) ) return;
" _% D4 }* h8 y' a) z! L
% r L+ e1 O4 p1 J$ y$ X+ Q long nCount=0;
Z; S6 v8 A2 k. _8 ?9 T6 }% @ spShellWin->get_Count(&nCount); // 取得浏览器实例个数, F$ ? G/ ?! m, |0 _' d9 ^
; c, B( P% q9 l, e, I; ^. T5 i for(long i=0; i<nCount; i++)
: J/ d# o" Z, r Y. U4 i2 U6 B* J {
c4 T2 s" R2 E8 \/ w$ `' p' R CComPtr< IDispatch > spDisp;* o+ M& ]) r9 J9 k+ R6 B
hr=spShellWin->Item(CComVariant( i ), &spDisp );
% w; W* Y3 ]6 V7 k; _9 X0 W if ( FAILED( hr ) ) continue;: q% r3 K3 K8 b; G A4 v5 z7 l
8 o& @% k$ f4 b$ P CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
- |8 o& l+ [/ }( D8 S' P if ( !spBrowser ) continue;
$ `3 T( ?2 M j( H; l8 ^6 u" i8 }
" H" I4 W1 ?* M8 G. @) G; u spDisp.Release();
5 l9 b# x( H6 E# q7 t# l D0 U hr = spBrowser->get_Document( &spDisp );* J8 N$ N2 A [6 T* h( s2 O
if ( FAILED ( hr ) ) continue;
% u7 z4 t0 \: ]# m- J- P' |
. _( D6 W1 J* Q+ n% ]& j CComQIPtr< IHTMLDocument2 > spDoc = spDisp;0 O6 _. N% H. x, Z) {
if ( !spDoc ) continue;. Q9 i3 V$ w; k% y! r0 u
1 F/ g' e8 g& s @5 ^+ I. r- |" o
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
$ v. q T, j0 D1 O) z; d }6 A5 H$ b4 h- O, m: o
}
. o' p v: \/ ^- \& U1 w; o4 j. @+ V3 ?- ~6 V p
<6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: $ ?( W& Q- ?2 @" E1 r
7 m. B$ Z' A8 D L- `, D8 D$ s( q: H8 ^
#include < atlbase.h >
% d* p+ M% J6 ^0 m#include < mshtml.h >
! V6 T0 x' t0 S% B8 @. f' A#include < oleacc.h >
( v- p* S+ V6 i7 U0 }4 {5 D3 b#pragma comment ( lib, "oleacc" )
: ^4 V3 W. }, f; I* G& v
/ ?1 c: q" P h0 EBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
! w s I8 \$ q9 Q{
l4 N) r+ j4 ]$ k1 R TCHAR szClassName[100];0 {- D. |6 c' x
; X/ h" I1 J5 {+ k( h& ^ ::GetClassName( hwnd, &szClassName, sizeof(szClassName) );" U, R+ h7 @. Z4 x- {2 i
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )
6 {& r) ]) |+ U3 S2 m% ~! w {
5 N w! g+ z8 S9 j, K *(HWND*)lParam = hwnd;
) Y' Q: z8 N, l0 A* O3 d2 H$ R return FALSE; // 找到第一个 IE 控件的子窗口就停止) K+ ]: C% H% [8 \
}0 O) @7 a# I, ?6 b
else return TRUE; // 继续枚举子窗口6 \6 [% K+ P3 O+ I h8 N/ K5 j8 G
};
: j) d( {7 b; e9 r* k9 X; I
) g7 W9 p b! @void FindFromHwnd(HWND hWnd)
0 r: l- Q# E# a* ]5 {7 U{; }$ [6 U" n W
HWND hWndChild=NULL;1 N' p6 \+ r- W0 S/ s2 G/ n2 ^
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
% E1 _; A+ G7 z if(NULL == hWndChild) return;- M% i+ ^* d7 O
0 j `& @' }% V9 b
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );% h- H7 V' p$ J' d
LRESULT lRes;! f" z' G z$ [+ z) o
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
5 e; D/ |7 R& i% c a0 {
- B' t5 E! B/ A9 k) u: R CComPtr < IHTMLDocument2 > spDoc;7 M& x: F: X+ u5 P) \& ?# w. G
HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
9 b8 a) k+ T7 {* |0 d if ( FAILED ( hr ) ) return;
7 ^ G4 ~% K# o+ }: ^ ]7 Q( q/ D: R5 y) H" j
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
1 }$ z$ o# u2 h8 G \, [' d; E} |
|