|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
' W4 B/ e; K5 N* T1 Q/ q0 c0 c# g2 f. F: |" i
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。. G! d5 a9 u( i5 H0 o4 t
取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。' [, d- L& \8 ~( l$ v z) j
<2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。' t/ ~/ E; Y6 r
取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
6 T3 M+ d0 j# n H4 I <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
4 l2 O: t0 J7 R( |/ E3 G 那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: ( q9 P9 H/ ]4 n
1 w! J8 @) I" O1 K6 |CComPtr < IOleContainer > spContainer;1 F; Q5 C( k$ j# t) B6 a
m_spClientSite->GetContainer( &spContainer );
3 F& s4 z! n2 b" M) G$ pCComQIPtr < IHTMLDocument2 > spDoc = spContainer;8 @4 p/ A$ g/ V; G8 X
if ( spDoc )
' M' s9 n Z7 ?$ ?; T2 _( i{
# H: a( a9 W: j* z" J& @ // 已经得到了 IHTMLDocument2 的接口指针
, [: c/ G' ?. E# L' \. T}
' M. A. I& D: K# A
) f1 {% d+ |' Q <4> 如果你的程序是用 MFC 写的 ActiveX 控件。8 P+ ~; p/ [6 [4 Y5 r
那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& a+ n$ K6 V# N) S) g. Y6 Q <5> IE 浏览器作为独立的进程正在运行。
2 F7 {; u3 x7 S. \ 每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
. \4 T2 ]$ Q1 v3 I% [# m9 ^+ C% K" g: |) \( H& l
#include < atlbase.h >
( C) ]4 q% @; E#include < mshtml.h >( d( a) X; G& k* z
1 U! t! r ?) Gvoid FindFromShell()
4 e, p2 ^' k- @. T5 i; w{+ A. J, U8 e6 |# u' h- W
CComPtr< IShellWindows > spShellWin;1 Q! y# M# U+ S/ z8 w
HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
- S7 k5 p: L+ U$ L) b9 V. S1 Q n if ( FAILED( hr ) ) return;
! A, w( x' x6 |3 R2 r4 E5 A3 I; y$ ?1 H# _- ]
long nCount=0;+ A% a/ L' _& B1 A# c
spShellWin->get_Count(&nCount); // 取得浏览器实例个数! m; G& @" [, |$ J$ T5 a
& r3 P2 }5 a* Z- @; L: x% s8 F5 I; f for(long i=0; i<nCount; i++)5 N: G, V7 C! o* s3 W% L2 D/ ?
{
, j! I ~. {1 b; z8 |4 \- R& T+ W+ e CComPtr< IDispatch > spDisp;* h- G( E; m7 Y: l
hr=spShellWin->Item(CComVariant( i ), &spDisp );+ H; M$ i6 K8 ]4 D6 I, l% e
if ( FAILED( hr ) ) continue;, i8 p) A. a7 v9 X Z3 M% G
' R/ A7 o% }) t S1 Y CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
9 G& f/ u. `% o* s if ( !spBrowser ) continue;. ^% S& e3 e y! P0 M7 i
& Z% N0 t, ~& N% O spDisp.Release();
; P- C! a; Q$ h+ c8 T" ? hr = spBrowser->get_Document( &spDisp );
3 q1 R/ J% i6 W# k1 R* n# _# |$ Q9 k if ( FAILED ( hr ) ) continue;; P% ?7 h% t7 d6 {
t ?# B7 P; ^& U
CComQIPtr< IHTMLDocument2 > spDoc = spDisp;4 ` g+ H& X$ ?( E) A
if ( !spDoc ) continue;7 x- T5 W5 Y( m) C
3 c. W7 n" ?- ?7 B. L6 L6 m
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针8 h/ u; Q3 z: e- T. p9 d
}
+ X, @0 W' }: l% W& Y}! K, M3 j) b+ g0 L% a- B
" m' i1 a, o4 N7 N! _+ e/ c, r
<6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: . r7 C9 P4 f9 M! k' p
7 o- }. i: f$ T. B5 G1 _
2 B1 t4 g2 A/ z+ W8 ^6 P* B3 C' u#include < atlbase.h >5 O1 j- h) H& S# }
#include < mshtml.h > f( X3 ^) p n7 f( \
#include < oleacc.h >
. x' z9 g9 J" {0 m#pragma comment ( lib, "oleacc" )8 W6 J+ x7 g/ } h$ F/ ~5 Q
4 w& ^/ G+ s; T$ T! ]: ]# U/ N$ qBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)& h+ n' `# e% f, F$ |/ ]: r0 O
{
$ q6 ^8 ^! M3 l) ?, o9 \, M TCHAR szClassName[100];" }; N& R2 a1 D" P- M8 P! r
' y1 Q% O) K9 c( ]5 \ ::GetClassName( hwnd, &szClassName, sizeof(szClassName) );
; G2 N6 U; c) M7 L' j3 H6 |. @ if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )$ }2 N9 p7 S, b9 m( n7 J0 o7 l, u3 r
{
& U- ~- i2 }8 q& a *(HWND*)lParam = hwnd;
8 Z4 k* r3 n) r2 {2 y7 c# q return FALSE; // 找到第一个 IE 控件的子窗口就停止; p- x4 c2 H) g$ y$ k, Q8 J# s
}
4 b9 i+ G2 a5 q4 p2 K3 @ else return TRUE; // 继续枚举子窗口- r+ p" [" t3 {9 x/ J8 Q
};8 I0 D: V* E9 P$ s! p7 P
6 I* J L. B h
void FindFromHwnd(HWND hWnd) 9 M$ f) e& t/ ?0 }- }( e& e
{
h/ K% B+ |5 y/ p HWND hWndChild=NULL;$ W9 o$ I' r" A% y S' D
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );, S5 n/ Q7 g- i2 u* a
if(NULL == hWndChild) return;4 @9 H0 |8 B3 {. f
- w* a8 F( x% W# V/ R5 g
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );- K) r6 c1 k4 x2 R; a5 A
LRESULT lRes;
+ t% G1 X4 \8 u- x ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes ); F3 z9 Q8 u$ d1 l
/ S8 C6 y- a6 I! O; W8 z
CComPtr < IHTMLDocument2 > spDoc;
8 e% E$ J2 T% a) w i+ f; @ HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
* ~3 |# p7 N+ G# N* U" Z if ( FAILED ( hr ) ) return;3 e! e4 I% y- `4 J+ {" }/ `
5 [( N3 x1 b% ?# T& \- h2 x
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针" {; ]7 H' r$ \4 T! _" v$ k& {: a
} |
|