|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
( E/ k1 |1 H$ H5 m2 j {1 G! C# }! l
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
; j6 U$ k) r' A# | 取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
3 G7 r! v. l# i& Q" l' V <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
" X) s: Z1 m% a7 Q h 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
* f( H* r! V% u* W <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
& J; I. Y* n/ |& X# w6 ^8 P. i 那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
3 ~" v8 A/ Y# Y3 V2 L8 z) Q' P$ q% D/ |. m& \' i- K6 c
CComPtr < IOleContainer > spContainer;
6 [6 y8 h: Q# Y/ O! T, c! @! @. Tm_spClientSite->GetContainer( &spContainer );5 y6 {& n" L( h* P$ x4 x
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
2 m) u8 O" k% x; p+ _' ^if ( spDoc )
% }$ S# H+ `' E" x{
1 t: |0 |. Q h% d1 F# Z // 已经得到了 IHTMLDocument2 的接口指针
9 K; C! q6 e# \) R2 X0 z/ f}
: t- N3 ?$ W I7 y" V; s1 G6 u% l( i, X1 V9 ?" s
<4> 如果你的程序是用 MFC 写的 ActiveX 控件。
+ u# v$ o) ^7 r; b( h$ g. U5 b! R8 z/ _ 那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& {" V. J& A8 G+ x+ `+ l <5> IE 浏览器作为独立的进程正在运行。
6 w# h$ j: w$ D9 k$ x" K 每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:# h' m: L# I8 g7 B3 p
p) [* `* |( f1 T) }! m4 b' v#include < atlbase.h >
* l# u8 O# K5 c- y. `5 H#include < mshtml.h >: A- Y( E; G O$ A
! N/ K7 g8 M9 f3 ]2 `void FindFromShell() ; ~9 f. c* A. f+ p
{7 _: v3 m6 f3 B1 L1 ^
CComPtr< IShellWindows > spShellWin;
8 S) E8 O" D, u9 B HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
0 d8 P+ F' a' y" q+ `$ y5 r if ( FAILED( hr ) ) return;
) P3 w# D, N' }, k; g' S$ \
/ j! ?+ j0 e( b' h/ ?: | long nCount=0;
* a& k& g. ]. t* ]9 m spShellWin->get_Count(&nCount); // 取得浏览器实例个数
; J. o1 r% @0 c2 R' D% y
6 x2 F! [) E& q for(long i=0; i<nCount; i++)
u# x* L$ P! m+ K# G {2 |, B3 Q3 l {8 V% w
CComPtr< IDispatch > spDisp;
3 u; s& K1 Q' K7 `' k* c* N/ I hr=spShellWin->Item(CComVariant( i ), &spDisp );
7 t6 ^# {0 d, a if ( FAILED( hr ) ) continue;
) h3 u: C6 q" ^4 u" \5 }% k" ^7 h
1 v5 g1 j: P$ `9 l) _4 d CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
* d% r, r* Z! g! a+ z2 W% h if ( !spBrowser ) continue;
5 `2 d' ~! o5 @, m) e/ x+ n2 {0 h2 L/ ?9 y: g
spDisp.Release();) S s( _4 y$ n1 c' N" p& M0 |
hr = spBrowser->get_Document( &spDisp );
6 P" A/ X" y# M if ( FAILED ( hr ) ) continue;
; D! F" W. h$ }6 z/ A3 v- K& u! C; K' k+ X6 V4 `! }$ o+ `4 d3 ]& m0 E
CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
$ P- y! L2 Y& G" R$ Y) Q if ( !spDoc ) continue;9 P" }9 q f2 g# d& M
+ j' ]7 K* C7 x
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针3 i$ ^& N8 n/ K1 M4 J l: R
}( j# G$ S9 U& A/ ?. n5 }/ a2 V( s
}
y2 q7 J0 m+ n n
; {3 H* n! k4 J* Z/ w' n <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: # y! [/ x: P6 k! n, o
w9 k7 y Z8 [! H" I# g1 r
9 J9 H4 q, A! ?8 S% j
#include < atlbase.h >4 `2 Y# Q7 n- q; z9 L
#include < mshtml.h >* C5 ?) t) h- Q- Z. e, P% C" v
#include < oleacc.h >
: o# h: z7 p& S) B2 z V#pragma comment ( lib, "oleacc" )0 o k9 \0 s3 P1 X8 W( R, C
) B. L8 W' r$ L- g& cBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
0 |7 m4 k4 v9 u! n{
" i- v& j- `& g; m7 P TCHAR szClassName[100];
0 V' ?- A3 Y- c! r
9 [+ `' O0 @) Z) C0 s/ J4 } ::GetClassName( hwnd, &szClassName, sizeof(szClassName) );
3 P+ d6 U3 U# k7 i7 j5 c if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )
/ s; ], u% [' O( b/ k p {! S7 S1 _/ i$ t! P1 l+ F
*(HWND*)lParam = hwnd;' l+ I+ T' Y" N
return FALSE; // 找到第一个 IE 控件的子窗口就停止
3 U" k- R' @2 s }! u+ L) ]6 c: h, V3 v0 G8 B- {
else return TRUE; // 继续枚举子窗口- l/ N; r) @) i0 @: {8 s
};7 l( {2 R0 o) Y! S
' ^+ Y; R% k8 ?: p
void FindFromHwnd(HWND hWnd) - F! R" d7 |4 M- K2 X9 t
{4 v' V* u# k! h& h8 Z
HWND hWndChild=NULL;
( s! r3 Y0 H# p2 P" U4 V2 J" ? ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
r2 [% [1 `8 {4 |; t+ L1 L6 t. g if(NULL == hWndChild) return;
8 O2 o( B: p0 o- x
, X- v5 E2 U1 G& u( D5 U UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );( P' Y. d+ H( U9 u' W" v
LRESULT lRes;( e& D5 I: \6 a8 Q4 {% z% c
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );- z$ C# Y0 u1 W, ]) a2 h
: l7 R& a' [3 ]
CComPtr < IHTMLDocument2 > spDoc;
: I" L* a0 n" [8 F- B$ y HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );! a9 y# z. e2 ]# ]$ T& }( I
if ( FAILED ( hr ) ) return;% D/ ]2 O4 R+ `3 M% Q
, a1 b8 J) a7 e4 c T' z
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针& A s4 Q: _0 b
} |
|