|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
( a# |4 o9 F I% Y" s! C% O7 L& X2 n
<1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
8 [- h, w! q! b" [2 f 取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。: M9 ~. h5 v, ^
<2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
$ W' Q5 u2 t) O 取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
3 E0 \' q4 t" E; n9 a <3> 如果你的程序是用 ATL 写的 ActiveX 控件。& \, |/ z* Y8 i7 `
那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
7 {" d4 t; t7 x$ z& N2 `0 o
% ^2 `5 X |7 |( m0 v5 U: y- GCComPtr < IOleContainer > spContainer;! D+ A# b" @. A0 f( M0 ^( L
m_spClientSite->GetContainer( &spContainer );/ ]0 f- G5 G! ^8 Z1 a. q
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;# H1 D* c) B) x3 k* O. C9 E6 g* {& @
if ( spDoc )
3 a5 H* u; p2 u: s4 K% Y{; v6 E; q0 [# z! ^: \7 l6 M
// 已经得到了 IHTMLDocument2 的接口指针
, a; j; Q# N: d0 [4 [- w( ~}: v- V. r# H0 s) f& e
# @7 v$ s: o! F6 f# X @ <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
8 i5 s3 X; O! V8 N/ s# B$ {8 | 那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。0 Y# \9 m2 _! ?! V/ P/ M
<5> IE 浏览器作为独立的进程正在运行。( r9 } _2 [( q0 f# G
每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:8 F: K% _" w3 t8 U
" u' P1 V4 T& i
#include < atlbase.h >
: A9 h% x7 f( X& f1 q' Z! o0 B#include < mshtml.h >
: a; _8 {1 y; m* G
+ ]' I' e3 \8 w2 C8 K; _8 J1 M* wvoid FindFromShell() 6 ?" i# T" l$ d1 z! g7 W0 ^
{
1 e1 E6 T! z; v$ z. A' `1 r CComPtr< IShellWindows > spShellWin;5 Q2 J: d/ O& D7 K% O @: |2 _
HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
6 E9 S0 [7 x5 e: \! s if ( FAILED( hr ) ) return; L$ K( x5 R* E8 r2 f# Q
6 S& o& {2 M% A P# N! B long nCount=0;
9 e% @) r6 ]+ o, B9 s d spShellWin->get_Count(&nCount); // 取得浏览器实例个数
- q3 w5 m1 t( { D: v
. m+ z# a2 W& L& e) i. S for(long i=0; i<nCount; i++)
$ w# P' j. g$ }, }1 O {
: N0 h: P) }3 C9 ?) B( e/ w2 Q CComPtr< IDispatch > spDisp;
, ], ^! C) h& }" _, Z hr=spShellWin->Item(CComVariant( i ), &spDisp );4 H- y! s8 c* w6 _$ i
if ( FAILED( hr ) ) continue;
1 W# ~# s2 V8 v7 U" s+ ]4 I
' m2 }+ }5 R% Y. p1 G5 R b" C CComQIPtr< IWebBrowser2 > spBrowser = spDisp;5 O5 F; y; C7 `! V( L! Q
if ( !spBrowser ) continue;
7 Z+ U \% N2 w4 K D7 u' }8 ^: A
* Q) Y6 E/ L. l# a: Z) S2 r spDisp.Release();) W9 _: l5 b, R* q& i# j5 P
hr = spBrowser->get_Document( &spDisp );: V& T5 d" P- ^, o
if ( FAILED ( hr ) ) continue;: [6 a9 y+ a+ s6 U, E
; [" A0 `0 t& k7 Z9 m" ` CComQIPtr< IHTMLDocument2 > spDoc = spDisp;+ ^8 T; w$ ]1 l0 \1 n7 M
if ( !spDoc ) continue;
' F* i j$ w2 K5 T A
8 q% k) |( M% s& y // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
3 N' O! s6 l, ~: s }9 G( n5 T3 G% j, t
}
9 B; r/ }' I7 @
9 h: u$ m* R+ \ <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: . i& ^! m6 | n/ P1 L% m* t6 ]5 I
7 g6 Q( |. v( l# v+ n6 k" F! C8 ?* d$ R+ O1 J/ I1 M. G
#include < atlbase.h >. \/ W5 Q7 E7 |, {9 {8 d$ q1 H
#include < mshtml.h >
( }4 @$ l! m* A8 q) ?9 j#include < oleacc.h >. \: L8 Q" \2 V) T8 j6 p! |
#pragma comment ( lib, "oleacc" )0 k5 v6 S f p9 C) c
; W2 A9 R0 u2 Z, gBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)" W. m/ V) g! `3 D# ], |' N5 r
{ g3 x+ v, v0 [5 {# h
TCHAR szClassName[100];% J# |/ a' O$ E7 H9 [: `+ a$ ]/ m8 m
S8 `3 x: i- W
::GetClassName( hwnd, &szClassName, sizeof(szClassName) );" p/ u: E3 T$ o& `+ _3 }! R& E, b
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )* N; F' ]7 l3 \9 s% `
{
, O+ w. l* b5 x0 b$ \8 l *(HWND*)lParam = hwnd;
( F$ {6 ?7 Z1 H return FALSE; // 找到第一个 IE 控件的子窗口就停止
. D: N5 K+ C; X7 ^ }, k% A! P) p2 @& @$ A" x$ j r
else return TRUE; // 继续枚举子窗口
- J( R( m' F O" o};
) O0 s% Z/ S* d" o }0 }; }! N, i3 K, k5 X D1 A8 p1 z0 H3 c/ F" w
void FindFromHwnd(HWND hWnd)
, L( a5 e) @6 d. N9 J0 k3 q{
. M& r9 H7 O9 _' j HWND hWndChild=NULL;
: X% M4 f# D: @ k ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
' J! ]5 Y7 W. q if(NULL == hWndChild) return;
3 ^4 j1 B6 q1 u, @2 o& a
6 m; I' U- t2 p% w! p& T UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
& {/ x. `5 U& E- \2 i/ F LRESULT lRes;
4 K2 i2 V1 T( `: O$ `: x ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
3 _0 h3 z9 \6 ~ o! S
, u/ Z- B" k4 n9 H CComPtr < IHTMLDocument2 > spDoc;" G3 w; [5 P; I+ U8 O3 z
HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
" E3 F9 x) Z( u4 H) W if ( FAILED ( hr ) ) return;
" O V+ p/ q2 o/ `: E. R4 ~& o# |) @4 R$ N% g
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针4 H7 t* n- f% N7 ~$ @; w6 {
} |
|