|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。9 N( ~) d/ n+ `/ J
: g; K! H1 M5 [+ q" _8 v' K
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。% {& s# T0 P* W: w/ l
取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。' l$ b {7 P$ r b1 X$ T' a% @- D
<2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
. Y0 M5 t7 j# b% [ 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
3 |0 J. m- D, `" L) y9 G <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
) b5 I" B1 N# ^/ @$ t0 J: ^ 那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
8 J4 L( z" P- p% d
, y) S1 E/ B. \2 j/ r, R4 j! R* nCComPtr < IOleContainer > spContainer;
# \5 U2 x Z0 t1 m& Fm_spClientSite->GetContainer( &spContainer );: {7 O( z' V/ c; _7 X
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;/ j/ c5 s; U* F8 N
if ( spDoc )* {" j- A" D0 S! a
{
2 v( M, {9 I3 f y$ S/ H; A$ {( \5 \ // 已经得到了 IHTMLDocument2 的接口指针* u5 Y- u& j0 ~
}$ C# e: A1 N3 x) @' Y6 b; ?
/ s7 C" \* Z6 f
<4> 如果你的程序是用 MFC 写的 ActiveX 控件。3 N- u8 p( Y3 o) m/ [; R
那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。; \. s* y3 ~9 R4 {0 Y( g$ r
<5> IE 浏览器作为独立的进程正在运行。
! y, L, D+ C6 J- B: P 每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下: o% h. w, ^2 e) V Y' a8 X4 V
! n( w" `: H* s6 R#include < atlbase.h >
4 m: S( v$ B# g9 }) x#include < mshtml.h >
3 n& p+ i' v7 o' [6 q' t5 d+ o
# G$ V7 \; V. [void FindFromShell()
9 }3 { q, f* h g{7 z$ i0 _) F0 J
CComPtr< IShellWindows > spShellWin;
" |$ ?( t4 M r. c( l) K HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
& _# @: j$ m4 I) a. U if ( FAILED( hr ) ) return;
4 v ?% i6 Q; t- {0 A/ A0 t. w
+ a# I( f# a0 b0 { long nCount=0;
q8 M% s6 r5 N2 p5 [' f0 ]0 O spShellWin->get_Count(&nCount); // 取得浏览器实例个数
& ?1 c9 Y' N+ j# r4 x* t% j4 L. g: e5 g4 A" w3 D* E
for(long i=0; i<nCount; i++)
3 D+ m8 S% k! ~/ C {
. Q) V3 Y/ H9 ~0 A6 S8 D CComPtr< IDispatch > spDisp;
8 E! X& _. W' V1 ^$ h" P& d hr=spShellWin->Item(CComVariant( i ), &spDisp );
, X. P0 ~ b' R if ( FAILED( hr ) ) continue;
* t: D: d q4 c' c/ A( |. }) Z* y1 |5 S% ~
CComQIPtr< IWebBrowser2 > spBrowser = spDisp;1 _% M. U2 U Y# V& [
if ( !spBrowser ) continue;8 t% j* v& ?1 Z/ ~( v
f9 D4 y. M5 K$ `3 z spDisp.Release();
' ]; Y4 m! t* \+ Z hr = spBrowser->get_Document( &spDisp );
) B5 j7 I! v1 p* w2 p# }7 X# a if ( FAILED ( hr ) ) continue;( O# g" s% o0 R9 B& K1 Y
# _8 y; Y9 d1 H& q0 D/ S3 \, P CComQIPtr< IHTMLDocument2 > spDoc = spDisp;4 a) Q7 ^9 l6 w/ q0 U; g/ Y3 t" ` w
if ( !spDoc ) continue;
9 j0 X6 U9 t8 x) j. C
. J( C9 n) h& O5 M // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
1 g3 e8 r' X' D; ~$ @ }9 D: Q" I- v' w+ n% @# i
}- k4 {! Q. B T7 H$ p% I
% o5 ^4 i/ H9 |1 u <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: , U. H% \0 w$ r" O
/ |9 w; I0 x* l
! S( \: O7 t/ G5 S#include < atlbase.h >
0 [: |! S. T( [( b#include < mshtml.h >
3 @6 X3 s2 c- }. m; }#include < oleacc.h >+ t1 E8 G O4 i2 k( T7 U
#pragma comment ( lib, "oleacc" )
( d- W- p" M4 x0 @5 L2 h4 ^5 v1 u6 O- M% X, a# `6 ?! d) a
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)! S' Y4 g' ~; s7 d* Y- z8 t8 _
{. |+ R, t# o+ b2 W
TCHAR szClassName[100];) x/ j; c% I" E
5 z# Y* G2 P. G) N6 T' p9 G/ p ::GetClassName( hwnd, &szClassName, sizeof(szClassName) ); q; m9 a, Q4 Z
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )$ b/ y0 F' [" m( [) {
{
( X' _* {+ k8 S! ? K *(HWND*)lParam = hwnd;
- ~5 u7 l# l- G& Z. _( u' I: s, H return FALSE; // 找到第一个 IE 控件的子窗口就停止
& K* t2 w, K5 _9 ~: | } V' T7 Z/ }$ C, i. y/ f
else return TRUE; // 继续枚举子窗口; k( U2 I* s2 Y7 i
};3 E3 N/ X! l8 |2 H
! R3 }; ?' t z" A! J
void FindFromHwnd(HWND hWnd)
! {9 o1 K3 w( S- b# V0 W{: x6 j1 G2 y7 `. b
HWND hWndChild=NULL;: a2 J) U+ z7 M- s- D
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );1 ^9 T$ Z5 s: K
if(NULL == hWndChild) return; I" T% g' l( ?0 }4 x+ K3 Q
6 K! o) ~" ~# z( b2 [
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
8 D! v+ r9 X \ LRESULT lRes;& V$ n/ e, J0 Y
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );# b4 i r7 @/ v$ U* l+ h* u
& e: A r( i: D" U
CComPtr < IHTMLDocument2 > spDoc;. x+ V+ o. Y6 ]
HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );0 Z$ a6 j1 N2 f# a+ E( M
if ( FAILED ( hr ) ) return;! o# L) Y) y# L0 a. Z4 u
4 v- e& a# Y! j2 U
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针$ I3 Q' p& S U% j% {
} |
|