|
|
根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
, E! d6 B# i* _; c
7 H, _- ?, O( u <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
0 y! r( O0 V- O. l! S3 x& H0 } 取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
! ^) `% N: E/ v8 h <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。3 L/ g, e0 {. o5 G' X3 M
取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。, @) o8 }- L7 b% P, p- k+ m* C8 v) G
<3> 如果你的程序是用 ATL 写的 ActiveX 控件。) |) R. q. s9 f. e1 \* ?
那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
6 e, G$ v" d3 n( Z; E6 e8 m P# c% ]6 ]! Z
CComPtr < IOleContainer > spContainer;
; B( C# v6 S& W. q7 Um_spClientSite->GetContainer( &spContainer );" w) ^9 k; W& Z
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;& b: }7 w% r$ X# v
if ( spDoc )# C) m! h H+ C7 P# j1 D
{7 o4 S4 Y0 f; s: Y5 D0 G* N
// 已经得到了 IHTMLDocument2 的接口指针8 ] o; i, v! j1 e* g% O. P
}
4 h, T4 g7 y# g$ P f7 G! U2 d/ o* L8 o/ a, h9 I
<4> 如果你的程序是用 MFC 写的 ActiveX 控件。0 d, `: Y. L, b, W$ {9 q1 m
那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。% t! v/ D# _. l: T" d D
<5> IE 浏览器作为独立的进程正在运行。" b/ R- u& B7 D; y% ]! `/ S# m8 x: p
每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:' n; R8 R& l) C' F" g- e* N
/ H/ Z" y: C T* |+ M$ Z- u
#include < atlbase.h >( H# k2 f8 Z& g, `8 f# C0 s
#include < mshtml.h >) Q! s K9 N, o1 f
1 L4 l1 B# I, d6 A& f3 t1 r2 Fvoid FindFromShell()
( m' ]2 W* L, ?2 F7 Q. Y6 O% w{
, m: e: Y) J3 S, D* ?8 k CComPtr< IShellWindows > spShellWin;
6 P! ?4 m# _ M/ E9 W HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
, I( Y# B" Y9 E$ s% C7 x2 B2 k5 x1 d if ( FAILED( hr ) ) return;
# d: |5 |: H& m$ Q" m; C
* _; Y# [1 d/ S0 @1 X% e long nCount=0;$ a+ u# h; P3 {" G: a3 I1 {% u
spShellWin->get_Count(&nCount); // 取得浏览器实例个数
- B: A- {8 Y/ R8 j/ z$ f
$ y }& W9 V0 ]8 K2 O! A" k$ N for(long i=0; i<nCount; i++)# P6 t5 F* ~! b; F, N
{
+ M! I; @$ n. {4 w CComPtr< IDispatch > spDisp;
1 h I K5 J( D# d4 i6 ` hr=spShellWin->Item(CComVariant( i ), &spDisp );6 Y0 @- G% _3 }, @% x" s, T: L1 y
if ( FAILED( hr ) ) continue;& s+ d5 G2 C6 e. ?5 W
0 P K4 |0 o7 J: h" } CComQIPtr< IWebBrowser2 > spBrowser = spDisp;- v' R8 C7 u% I/ i \( I) t
if ( !spBrowser ) continue;
. X8 J6 @' s6 Y
+ e( U& C* `: J; u" o spDisp.Release();
X' Q3 I, H, T# O hr = spBrowser->get_Document( &spDisp );
. R3 f8 [ N; b7 \! h9 q$ y if ( FAILED ( hr ) ) continue;' t( @1 q+ O* F1 y4 m. c2 w: ]
; Q5 F7 U) \! x* z2 }# g CComQIPtr< IHTMLDocument2 > spDoc = spDisp;2 i( w0 S" k% [; R' ~, ?8 Y
if ( !spDoc ) continue;
4 r: W3 O2 H; ]& V4 Y7 |1 ]5 M/ b8 V6 g& P) M
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
4 x$ x% F* _6 p- l5 J3 T }
3 P7 s) Z! \4 `}; h3 n& B0 c a2 v9 x" Z
2 o9 B7 m4 f5 P1 T0 o# o$ O# u$ ^
<6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: / U: K7 q4 H" Y# n; E3 D9 [
. |1 e7 u2 E* g/ E
( p$ C |" G8 @6 [, W#include < atlbase.h >
; `. A' h# K# S+ A#include < mshtml.h >" r4 P, _- A) w+ w6 l
#include < oleacc.h ># T# A E8 c. h- ^6 t
#pragma comment ( lib, "oleacc" )
9 u% K: @' Z8 ^ J( ]: r* `8 `! y
$ U# q0 k& [% fBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
- w; R, W% B& [, ]. l8 p{
9 Z& K/ A" A2 m2 E6 o& b TCHAR szClassName[100];) K1 c# q, Q% G' I6 a9 f$ u" w
9 T* p4 r7 g9 S4 \$ T3 }4 P0 J; _, J ::GetClassName( hwnd, &szClassName, sizeof(szClassName) );* A8 Y/ f+ e! V: x2 H
if ( _tcscmp( szClassName, _T("Internet Explorer_Server") ) == 0 )
: B6 D8 }% M: ^1 f {* B% m( D% h4 f$ X
*(HWND*)lParam = hwnd;6 w2 K* R& S- H& d; D: w v: E- t, }
return FALSE; // 找到第一个 IE 控件的子窗口就停止, C. f' k% J# q, Z
}
: w! a/ h' B* `* I else return TRUE; // 继续枚举子窗口+ ? x K5 j5 A4 I/ ]
};
' \! \( u' B% m$ m# t& \) d' p& d7 N7 x
void FindFromHwnd(HWND hWnd)
& A* ^& M! R. T/ B2 u{
: k0 ?3 j1 c% _ HWND hWndChild=NULL;
! j& L( I7 \* ]. ~4 a ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );2 Z) }* t) y9 p9 w4 S
if(NULL == hWndChild) return;
8 A4 h2 _$ j L3 m2 Z; V7 |+ Z h7 ]. g/ I8 k5 S# n
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );3 D2 i. l: a- ?* q9 | R2 ]# R
LRESULT lRes;+ f) k* i( d3 A. V
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
, V' {. ~+ H" ]' f6 }0 \: g
2 p* N/ k+ \3 i# m( z8 j; y9 r CComPtr < IHTMLDocument2 > spDoc;
9 W2 y1 L) z4 }. a& _; g HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );; X+ s) v: A$ t8 R0 x
if ( FAILED ( hr ) ) return;
) W2 K( e* {2 r6 V3 i* I! D3 i$ z' ]% O5 ?/ g% ^" F1 C+ Q
// 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
; F! L( Q2 y: d1 _; ~, e5 b} |
|