找回密码
 注册
搜索
查看: 4530|回复: 0

[收藏]千方百计得到IHTMLDocument2的接口指针

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。6 U- S4 W1 J* Y; k1 ]# @

& M/ ]' ?/ `5 u: F' q  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
) h; H  Y2 b) d% T4 Q6 k        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
4 t7 E+ A7 J( p% A- y! ~0 Y9 \  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。! V/ w* z" A, {+ q
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
* j; i. }: S6 q2 F8 s$ o7 v4 D  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
% w" z/ H0 s4 x. b( Z5 {4 a! f0 o" Q        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: / q# j! @# ^" Z* S
; t' [1 K; q8 e+ T; {
CComPtr < IOleContainer > spContainer;; t$ }1 x) ~( w( c, B7 q. Y/ b
m_spClientSite->GetContainer( &spContainer );+ e7 H+ w- l! z
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;, r4 Z2 D( R0 i: l" A+ ~$ A1 e. O
if ( spDoc )
7 ?, ?& d$ ~4 N/ F5 j8 X' `* @{
4 K. W, q/ h) I, p. r' O     // 已经得到了 IHTMLDocument2 的接口指针
0 p# _, G& D5 H  f  H: ?}
1 m0 C% e# {, l0 X
# h2 N) Z6 @/ d1 q5 z  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
. X) x$ `1 V5 X7 [# Z        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
" i! H+ K; j" m7 Q) y  <5> IE 浏览器作为独立的进程正在运行。
5 ~" K+ u- P- m- f! I1 ]8 W9 W        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
0 l( B+ U( q, |$ j' s. {1 x. u- A# N/ _" F/ k
#include < atlbase.h >+ T' a6 l( n# H1 r% |: n. x
#include < mshtml.h >
* _* g. {. [" t3 j9 t
7 A0 O1 a1 o0 l" I$ o4 U2 Vvoid FindFromShell()
. S7 l0 ~+ E/ w2 k7 K5 q: `{
# J0 @$ \! i$ q1 ~1 Y- i% R. A   CComPtr< IShellWindows > spShellWin;
$ d, p. A0 e9 @8 L1 M9 R9 a2 k8 ]   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
! `% D# Y  [& r/ B& \* y7 d/ R+ c   if ( FAILED( hr ) )    return;. M1 e: P6 ^( R( A& w+ t
* L; J6 D' i6 u7 \
  long nCount=0;0 J0 m% A: u- E+ S% }; Z
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数- ]$ [& ?0 N3 m

7 h: Z+ U7 Z( e- q   for(long i=0; i<nCount; i++)8 B' d2 j4 O3 H, o
      {
4 B: _* o2 L" U& G) Z                CComPtr< IDispatch > spDisp;
, n8 P# x4 y' r: P      hr=spShellWin->Item(CComVariant( i ), &spDisp );. N, _0 `& @+ b/ x
     if ( FAILED( hr ) )   continue;
0 H5 e6 }8 ~! ?5 M' f' |6 N/ Q9 F* H3 n! O' x! g! D
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;- s) b1 a8 g( m: t4 f
     if ( !spBrowser )     continue;6 a7 @) f+ q4 s3 }7 S5 i3 j4 w$ J( n

+ s; E7 e' e* j& \4 b' p1 d; e      spDisp.Release();
" D! h1 _% J: c1 @' l      hr = spBrowser->get_Document( &spDisp );7 w4 Z6 D/ S2 F+ }  `
     if ( FAILED ( hr ) )  continue;3 R: \/ g8 A! {# o$ F9 ]7 c
! S7 d. K. `4 o0 F6 o8 U  K
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;7 @4 l& `/ L6 o# s: d3 Q7 Z
     if ( !spDoc )         continue;
" a0 h( X  [. V8 S
' W2 X% h1 q: ^3 M0 j# U0 N      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
% `2 @, o4 I$ O  D   }$ A6 `9 Y# W- N' V+ ]. V
}, W; H" u6 T( y" R0 s0 a+ D" }
; L1 K$ A, y9 n2 D
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
9 y: ^# \' r! g) r8 Z7 I  L1 k- c
, P+ G) ?+ f8 ~# ?
5 B; Y# b! R' X- ~  {#include < atlbase.h >
7 d0 e1 k! S# Y8 C- i$ m$ i4 H#include < mshtml.h >+ }( n2 C9 @( E* e. M. ]
#include < oleacc.h >
) u4 J: ~. T7 K+ W#pragma comment ( lib, "oleacc" ). G) I; `; a0 k: ?
/ p+ `1 e: I; I
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
2 [* W0 s1 N, C* J{: w: S2 T7 @$ L2 B& x  \  y
  TCHAR szClassName[100];
5 x; i! G( A6 ?3 l6 Z
, a' c: Y7 G* Y) a9 u5 B# M9 P   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );. ~9 E5 X% j4 X
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
% V: f4 E, `1 b! W8 u   {( i3 d! b/ q, z+ m* s
     *(HWND*)lParam = hwnd;3 ?4 g0 I7 J$ }; J
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止( L3 f$ p% R4 h8 v1 E& \/ G
  }
/ l( D! }) s$ q* `% ?# |2 p( d   else   return TRUE;      // 继续枚举子窗口
1 W# ]6 A5 o. h/ v1 X! K9 t1 `2 W0 ?};
6 Y# d$ ^0 Z4 F1 @1 G1 e# I3 D
void FindFromHwnd(HWND hWnd) 7 l, k; M  r* [, D+ k  @" B3 s
{
/ S0 x5 r2 @% G9 Q, f   HWND hWndChild=NULL;
3 A  p$ M8 m! E+ L' s3 y   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );, K8 \& ]5 u* k; B; m, L! r
  if(NULL == hWndChild)   return;+ D8 |! I: q) q4 u5 F1 f, j6 m
+ x/ c+ z- @& t4 B
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );3 @+ m( N6 i5 v+ l, B1 r
  LRESULT lRes;# a  j/ b1 j5 ]+ i
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
7 V% Q/ g4 e+ m0 V
  e. {4 z3 ~+ H" q9 D- i' l   CComPtr < IHTMLDocument2 > spDoc;
; Y! }+ K- _$ p1 c! C& {   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );, X6 T) t- k: v) z5 ?. ~4 L9 @
  if ( FAILED ( hr ) )   return;+ Q( R) }4 z' v  w
1 A  Q; b& C5 r, h
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针7 F6 c4 U2 Y. O" W
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-12-13 08:23 , Processed in 0.018722 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表