|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。' t- Z5 _* v( H7 \
Y, Y9 T5 W: H1 F+ d8 ?0 |/ J& q
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
, v# Y) r) K4 ~) ~0 y h 取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
9 ~( s% a ]+ H, G! t. z <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。- G) n. ?* `/ c# b% ^! \' d
取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
! U. ~* r9 h6 P1 z8 x# K3 q <3> 如果你的程序是用 ATL 写的 ActiveX 控件。* l& }& O; p; S3 T& G/ J" a
那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
* o* g( \% r8 M! E) B! h
3 \* m6 i( ` tCComPtr < IOleContainer > spContainer;
3 w" f5 r0 r* r& I2 gm_spClientSite->GetContainer( &spContainer );$ d: K9 ?$ n$ U- C6 F( U3 t
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;9 I+ Z5 ]1 f3 d" u0 Y5 a+ c: ~8 a& ~% t
if ( spDoc )- g% @( b9 H3 t t. k6 @
{
% J# t5 c& F( d/ H1 | // 已经得到了 IHTMLDocument2 的接口指针
% g7 \4 k9 ]$ A}$ @- p% \* K" u. |3 |* C7 P! N
; b* X( g5 }9 `! k1 h8 [
<4> 如果你的程序是用 MFC 写的 ActiveX 控件。
0 L) g! v b, D& f6 ]. } W 那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
0 G- |$ y# A G <5> IE 浏览器作为独立的进程正在运行。
' H! R. |) v7 S4 x7 H, C- } 每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:$ |7 Q$ g0 s* H) @& f5 ? P4 n$ |
( ?; [6 O& V- ?6 o
#include < atlbase.h >
5 E- h: I' t+ X' a3 O. k#include < mshtml.h >
6 m8 m' P, b, V
' y: }$ E" B2 i9 {void FindFromShell() ( S0 z0 X, `& g$ W6 M
{6 h8 h3 F I/ D3 J/ M* Y
CComPtr< IShellWindows > spShellWin;
" q/ x8 x3 e6 \/ A/ z/ p HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
. I" Z% ?# {, w+ M( @, g if ( FAILED( hr ) ) return;
+ A/ G- w$ k. ~! L! v$ {% L# m
: g/ a: e: r. V( ? long nCount=0;
' \/ d* E3 [5 {. L spShellWin->get_Count(&nCount); // 取得浏览器实例个数
# P S' j i1 m5 k4 d+ U- W# i4 l' ~- w" }# [- X
for(long i=0; i<nCount; i++)
+ ]8 {2 C" l; z- `" r' d {
6 B( ?, ~, a5 W CComPtr< IDispatch > spDisp;& t9 v+ F% Y2 H* g+ D6 G
hr=spShellWin->Item(CComVariant( i ), &spDisp );0 n0 D1 `$ O! {) o
if ( FAILED( hr ) ) continue;& @5 `# l+ Y; T3 t7 L
9 e" c0 \% M+ u" f9 q! t+ v7 k! ~
CComQIPtr< IWebBrowser2 > spBrowser = spDisp;9 I6 s& G1 A( o4 ?0 y* B
if ( !spBrowser ) continue;
: f$ A4 P' i& J% J+ k' ]: [5 |, s4 }" B4 u& x- N
spDisp.Release();
1 ?: F, F6 Q% r3 D) ~ hr = spBrowser->get_Document( &spDisp );
1 M Z0 E) N( T" A2 d& M if ( FAILED ( hr ) ) continue;( |" R1 ?1 R& z0 F* A: G$ ^
8 \1 i" G; i6 C0 e
CComQIPtr< IHTMLDocument2 > spDoc = spDisp;' q n" a* t! u# H4 E# A
if ( !spDoc ) continue; H% V: l' b" e: D3 j! i1 c: N
# U- F2 N1 U7 I$ J+ } // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
( [. m, u' _" S1 L }
/ k4 t/ L+ v$ g$ k" f5 u}
# m6 L& y1 M% c$ x9 o* H# E7 u' U2 w! U o6 X* d
<6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 2 A+ @. s7 Q; a' g( }; l" C
8 X$ B- H+ T/ B
% g. J' ^: U0 j) }# Q1 i# o8 L8 G#include < atlbase.h ># [( J! |) C. [
#include < mshtml.h >1 F! K6 [; b" ]/ ?, e* O8 x2 s
#include < oleacc.h >& V) e2 @; c& B' ]) B) G
#pragma comment ( lib, "oleacc" )
+ X+ W( ]# l$ r3 C7 E6 Y
# ]4 T* L( A% D% E! b# {, c% XBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
& z" H3 A) q6 W* y& S{* h; I& V1 ] b7 ]+ L
TCHAR szClassName[100];
5 X/ X" a8 C1 [7 I) E
9 Q0 W6 P7 T! B4 K, U ::GetClassName( hwnd, &szClassName, sizeof(szClassName) );4 `) Y4 Y4 U" k3 N0 @6 E+ n+ I
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )
& z2 u( d* C1 b4 u0 Q3 h* A {2 D+ i+ |* z, D" j, ~% }
*(HWND*)lParam = hwnd;) l6 T8 C5 b( a; r
return FALSE; // 找到第一个 IE 控件的子窗口就停止% g$ g* b6 v: o/ z1 f# E! w
}* T' S4 Y E0 Q' Q: P+ b6 k
else return TRUE; // 继续枚举子窗口
7 f2 n0 `5 J3 h0 Z$ \; e( @8 ]* N};
* S9 \$ O$ `" y1 G& X# Q4 r# a% R2 P8 M# {, O) e7 e
void FindFromHwnd(HWND hWnd)
7 k- F, A9 C- P8 F" ~3 Z" J{* ], I% T: N7 e9 W
HWND hWndChild=NULL;/ w* `7 Y2 T7 _0 e9 Z
::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );% p/ G" i6 w9 Y5 t0 m0 n* E
if(NULL == hWndChild) return;
: u8 Q( G& K+ ^* f4 A1 l3 b8 ]0 t* D8 T& S2 v% b
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );- b% D, E! @/ M3 u2 q
LRESULT lRes;
8 ] T" a e7 L) V3 u$ T# n# \ ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );' L* \' P N- Z0 Q; |
' v+ v! v; d6 z# [% `
CComPtr < IHTMLDocument2 > spDoc;8 j+ M: b0 R+ d* ?$ g8 [ y
HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );5 Y$ G7 Q5 O: f/ A- s: B
if ( FAILED ( hr ) ) return;6 e, G% f, D7 K
# I( s0 N K1 t9 b // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针0 J0 w4 F( q* `# x( Z* ]
} |
|