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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
; ^+ Z4 Y% B# V; S1 J8 r( q: r. ~7 G0 n
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
  w! k! e& J( R- {6 {; t        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。; B0 _6 W6 [" t: x- f- Z
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。$ c4 Y) p2 X  o! E
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
, V7 l$ o6 l0 i0 F1 x  q  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
" y/ l1 b0 ^: [: q7 t2 {        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: / B' S; v) ^; K* W4 F+ R

8 t  n) W& D/ z- FCComPtr < IOleContainer > spContainer;) y3 X4 P8 A9 f* y6 F6 L- `
m_spClientSite->GetContainer( &spContainer );
6 g% ]0 _( L8 PCComQIPtr < IHTMLDocument2 > spDoc = spContainer;% M+ X' ^  N: ~  h
if ( spDoc )# y  j5 a2 h5 C4 S0 X
{
4 [2 U' g& n  v9 f7 m- M" i2 w     // 已经得到了 IHTMLDocument2 的接口指针
& Q9 V+ l3 k5 k9 D( U}3 X. n3 [8 M0 X

/ Y2 k4 Z/ D& @. M  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。0 }3 [* }% w* ^$ N' J8 s( J
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。3 u; Y7 W! K0 v. V0 N( b
  <5> IE 浏览器作为独立的进程正在运行。
* B6 [, p8 y6 L) O        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
' }* a! O  T1 g: R( }+ V& |& K2 E4 [# P0 P
#include < atlbase.h >
; g5 k3 K1 ~/ X1 M) Z! Z$ U#include < mshtml.h >2 O( ~5 ^, U  ?1 [3 c7 _+ H8 ^# B
- r# Z" X; }! T, S+ t1 m! F0 I
void FindFromShell()
& e* P5 P; J* f7 I( Q{7 o. c; H- _! L9 g& z
  CComPtr< IShellWindows > spShellWin;7 O- Y. c9 p0 Y/ |. F
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );# E, s& }- q+ V# ]
  if ( FAILED( hr ) )    return;
& B9 h# {9 V  u8 D% o3 n& j* U. d" A: d* G8 q! W. Y
  long nCount=0;
. z" ^. y6 u# w3 _$ f) H   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数: a4 m' M0 v  @" k$ T9 B

% J; x3 `% i# g   for(long i=0; i<nCount; i++)+ H+ x* o! z. I$ L/ S! y
      {
9 [, N' l9 v# [                CComPtr< IDispatch > spDisp;
' B3 R: s: U3 M) h- ~$ |+ l      hr=spShellWin->Item(CComVariant( i ), &spDisp );
: q& n5 V8 p; ]      if ( FAILED( hr ) )   continue;( f9 N+ J! {- R/ Y9 J. t

- q5 E9 z! g2 e9 F) w; E4 Y. [2 e6 C      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
. F; I) m6 T; ~8 I      if ( !spBrowser )     continue;: }& f, T& b) L( a* v' h! e$ m
% c8 ~0 r( Z1 E: A6 E$ j. U' Q
     spDisp.Release();
6 i- K2 @4 r% ]4 v2 J      hr = spBrowser->get_Document( &spDisp );
# |" \# b+ m  n: g2 z' D* C      if ( FAILED ( hr ) )  continue;# F) u+ U8 T! G2 N

) ]  d8 `, k, z; y. {      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
9 M  A' g1 u) O+ ^" J9 s" E      if ( !spDoc )         continue;  P% e! Y6 N* E! G
0 k/ x1 {3 R  O: j, M
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
# M2 C: y8 l7 k3 G& ?) w) u. s   }
' |  Y7 y, [, Q}
9 A0 B: p5 L7 J3 Y, _5 E1 q- ^
* K1 C3 \8 l7 g: Q$ m  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: : R5 P1 ^: T# g. i7 n$ |- k

% s# w  O6 h! N" t
4 \$ ^4 w4 Y& ?1 w/ I#include < atlbase.h >$ h: e- B: N' B# R1 r
#include < mshtml.h >8 r7 v9 x2 l/ b1 U
#include < oleacc.h >1 E3 `1 {6 D& P  c
#pragma comment ( lib, "oleacc" )- v$ V! r! T8 F' b; P

' `+ n% A  Y. X2 iBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
0 i+ Z+ {' Z0 _+ I5 I: w" w{& b' B7 r8 H6 `) ^+ N: F6 y/ s& G' z& m6 s( h
  TCHAR szClassName[100];1 p8 ^* S/ ]8 Z; K

) s9 n% E: h! H9 i5 V   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );, f" J5 ~  N9 d6 w* I
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
$ E7 F+ g1 F3 P+ c, G* }   {+ d6 q" Z. x, Q; q" R7 l/ E  G, f. V
     *(HWND*)lParam = hwnd;# O7 ?3 w5 B) F9 O6 j
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止6 ^% k% w) z# Q+ j* t2 W3 m
  }
- R. c7 }+ {2 m. @! W! }) `   else   return TRUE;      // 继续枚举子窗口! x; _) I- v& u, _0 T0 D3 M
};  N8 a! x- h; Z1 U2 r, @8 }
7 n: i, p; [* I. F: x
void FindFromHwnd(HWND hWnd) ( o' t3 n" d- O
{
/ s4 i0 g: B- \- M( D   HWND hWndChild=NULL;% K# P9 s$ B9 r7 n6 i: k
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
; m4 Y/ S8 Z9 z7 E  a1 k. ~0 Z) @   if(NULL == hWndChild)   return;
6 B# I7 t( I  G$ H" z3 F: i1 Z, |9 q* S( n3 f
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
; E7 y- ?& M; X& ]   LRESULT lRes;0 w) v' b9 [) N  K* G
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
; K7 X! O' a* }6 \. e( j4 [7 l. ^' H3 |8 t/ K* T
  CComPtr < IHTMLDocument2 > spDoc;, a! w* ?. {: ]8 l4 h% E
  HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
# \6 o6 J2 n- B9 I: Y   if ( FAILED ( hr ) )   return;
1 u9 m' T9 O8 j0 ^% H0 R
- W( d2 _; T# X# ~: }( E2 B  y0 N   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
8 v6 _8 N1 ]; @  i; Z" h+ e}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-14 01:12 , Processed in 0.016999 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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