|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
9 l. i! B8 W& _, j7 ^7 b1 ^
. M& ~- {6 |* a* g- t% o <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
$ ]2 o' y3 o! `1 ] 取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
4 F9 H1 ]$ q' k, Y3 r1 h <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。/ u9 r+ b( o* j s7 o5 }
取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。+ Y0 a8 T3 d8 C4 g) ?$ Y2 s
<3> 如果你的程序是用 ATL 写的 ActiveX 控件。
; a; B% F K! b% D/ L! N" E1 J 那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: 5 y( r$ l# [( F9 K
8 ^7 `7 ?# p }" A2 b
CComPtr < IOleContainer > spContainer;
; x8 G9 f8 n. c" q" w- P7 {# Y- Zm_spClientSite->GetContainer( &spContainer );
( Z5 O$ |1 m9 k6 [0 ?9 D$ OCComQIPtr < IHTMLDocument2 > spDoc = spContainer;% ]! l- I& Z5 F" C2 N7 J9 u
if ( spDoc )4 R2 g3 W- f: ]3 c, O
{
( h& f, ~# m! ]" ? // 已经得到了 IHTMLDocument2 的接口指针8 U/ i& ? p% B5 h6 {: `
}
0 @( Q# b. U( k7 q. C2 c
" x' C9 O" C; H/ J- A! Q7 b4 h <4> 如果你的程序是用 MFC 写的 ActiveX 控件。. d6 r0 a# _! q7 l+ H) W3 s
那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
0 E# J7 ~& |( Q9 k3 E0 i3 a. Q <5> IE 浏览器作为独立的进程正在运行。
3 E( ~ s+ Y# [) N3 g( s 每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
" u: z1 ]9 |/ ]" ?: E+ B5 N8 p( e
#include < atlbase.h >, V. F, G, O4 p( P; [/ e
#include < mshtml.h >
! N6 L% p% O2 p- N n) G+ D( R' V5 M; }
void FindFromShell()
: t7 i% E W2 W* k) m9 H, S{
; t/ F, m2 \3 N: e# [( e CComPtr< IShellWindows > spShellWin;- O6 [3 T+ q. z1 C4 h* K
HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
: N8 @$ I% q- H+ t" ~" S( Z- _& T if ( FAILED( hr ) ) return;1 k! P1 Z1 g3 d' B0 |0 r
- O( ~- Y% f m0 J' p
long nCount=0;
% Z5 q( e" N( m7 e8 W+ K( i/ U spShellWin->get_Count(&nCount); // 取得浏览器实例个数
" l4 E, O% B$ X' D
$ _! }+ I+ T7 O3 K6 I for(long i=0; i<nCount; i++)
3 L" r3 w& M$ D1 Z V9 |1 v {
0 N& q {8 T& j& ~ CComPtr< IDispatch > spDisp;
; ]# I4 {0 ~% I5 H( P hr=spShellWin->Item(CComVariant( i ), &spDisp );; u/ w- i4 M3 n! J% A. h4 |
if ( FAILED( hr ) ) continue;
& j! q' T* V$ f6 B3 a
% ^ l8 |% M# G2 \ T0 N CComQIPtr< IWebBrowser2 > spBrowser = spDisp;5 s) N5 q7 h! ?$ Q" A0 D
if ( !spBrowser ) continue;
2 A, E6 Z* `4 b- U; Z! A& n% ?9 C5 O3 b
spDisp.Release();
( G6 I1 w) _. G# k. z hr = spBrowser->get_Document( &spDisp );
, r4 f; [8 j: [1 w/ T) |, T" M: \! a if ( FAILED ( hr ) ) continue;
4 _. y/ O# D* ?$ V4 ~; n# O& S( b5 w) H$ a
CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
) _* O* ?; n9 t1 c7 n* y6 G if ( !spDoc ) continue;
; T3 S1 p ~) U1 P3 `# E# j& O( T
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
2 m: S; q$ @8 b9 ^" @3 g7 O" F }8 k# V. e* W! F6 R
}
! b+ z0 H0 g3 D( K' {1 o' L- @, ^; y
2 ~5 E) E+ c3 q; e3 o' `4 G <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
; o6 ~/ ~0 I7 c$ f, A& @" s/ }# l5 l5 k1 j
: H% a0 T. ~% i/ I; x: z3 D#include < atlbase.h >
, C/ Y& I, ^( j2 D0 W: @- ]#include < mshtml.h >
; x1 z9 q* ~# j5 G3 Z$ }#include < oleacc.h >
. W( l; Q+ w! B5 I5 v' h) o+ T#pragma comment ( lib, "oleacc" ); J* j+ U Z4 g6 f, D- R$ r+ ^" ?
5 r( R+ v7 r0 j% f" O9 a2 y7 U+ z
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
. ^7 d6 t' n' \$ S& d- E# }& d* i. d{
1 ~3 [1 R0 f+ j+ ]' z4 G TCHAR szClassName[100];2 c4 n$ t0 C) M$ a
3 h( O. u2 [6 `
::GetClassName( hwnd, &szClassName, sizeof(szClassName) );# G* v% L, T A
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )
' i9 w7 v* H! ^* w+ G$ r6 V ^- A {- q. }% ^) i* s/ N/ C6 E
*(HWND*)lParam = hwnd;
) L; P% Y. _( e0 I return FALSE; // 找到第一个 IE 控件的子窗口就停止* V# C N: F6 b$ ^. {: o) {5 W: B
}
1 g1 `* |! P- \+ h else return TRUE; // 继续枚举子窗口
3 R ?' k l0 x! U7 O( Y4 g4 L};
/ U6 u$ ?/ R; u9 V7 i8 N! i: N6 Y0 C" `5 q: i+ ]
void FindFromHwnd(HWND hWnd) 7 J% M) D H1 ^1 Q) A' H/ K
{9 H7 z3 z6 V Y: S5 @
HWND hWndChild=NULL;
- ~$ S" Z8 G9 X9 L( W ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );+ F' }1 k1 z6 p$ D5 D. ^
if(NULL == hWndChild) return;! n: [8 Z/ v8 ?: z7 E+ Z: V
1 o" A/ @2 ?6 J% `7 G9 d UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
& E7 a: M" e! O6 L LRESULT lRes;
' ^4 w( A/ r) S% @( |3 f ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );4 b. [ Z1 n# F6 S. n
9 {% L% i' H2 q3 j+ n
CComPtr < IHTMLDocument2 > spDoc;
1 S* M# x7 ~6 a HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );3 K- z# Y( `, ]4 O9 g& X# j
if ( FAILED ( hr ) ) return;, D/ h R. S0 t( T' C0 D- F% v
" \5 e0 w. F' W" ?( F$ x // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针' v1 C6 ^# y3 h# u5 Z4 Z- ]
} |
|