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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
7 e% x. }) N9 `1 w, j! L4 b; j8 ?
0 y3 I7 r/ X3 P5 h3 ~  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。9 b0 W* F1 ?3 e2 S1 p2 l
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
3 A  U' l- X3 k2 J5 K/ u7 j0 \  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
8 w& _" [# S" ?- [3 N$ M        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。0 U0 Q+ j8 I3 {/ F- |5 [) _* Y
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
+ S) a1 C; T" K" O3 @9 b( E# m        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: ; ^( `# |" ]8 u

8 ^5 U; i2 f- GCComPtr < IOleContainer > spContainer;
6 N! a2 h5 R( {, e/ D. A5 _+ F: am_spClientSite->GetContainer( &spContainer );
+ t* c( Q1 E+ A  iCComQIPtr < IHTMLDocument2 > spDoc = spContainer;6 I5 C: ?! [. n9 n8 A# l8 g2 ~3 L
if ( spDoc )
+ L+ H8 R/ H0 A- g+ T1 ~1 c{
: v1 I, A* s* Q8 F  X     // 已经得到了 IHTMLDocument2 的接口指针
& C1 Z  n* N: s' s! R}# p/ L# }! t& }; T
5 S: J' ~+ S( B
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。, D7 t* H4 _8 E) q
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
3 m; A5 Y" x& V' a3 j3 }$ t  <5> IE 浏览器作为独立的进程正在运行。8 t3 e5 w7 V% D# C5 t6 F
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:6 G& D3 J" ^$ v" ~& |5 s9 C

# g/ D3 g9 {1 }" V3 J#include < atlbase.h >- y1 A# X/ f; f* _
#include < mshtml.h >& }# \9 F/ B; [3 z
3 t8 ]. d( `& O; y) |
void FindFromShell()
: w$ S4 A) k* a" t$ A) Y. O{
; l3 l/ {) c+ |9 a( s  A   CComPtr< IShellWindows > spShellWin;
$ {% ?3 F, O8 g, m   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );3 W. g3 t% ~  w# h' g- I7 Z. O
  if ( FAILED( hr ) )    return;* S1 t; t9 G" K# K6 n: p5 t8 E8 m5 w* Z

% [# d" _( m0 V' G  l4 a   long nCount=0;
0 l( l6 }! a, J; C0 O' d, C   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数" S: `1 Z" B8 b$ {! K$ i
- X, }/ P3 \- H2 s
  for(long i=0; i<nCount; i++)# q6 _" x1 w! e3 f, l+ o! f
      {1 Z, ]( h0 z' J' ^
               CComPtr< IDispatch > spDisp;
7 G; h) z8 Y$ q2 C4 S; t7 _2 j      hr=spShellWin->Item(CComVariant( i ), &spDisp );
5 N6 O% Y5 {7 ]& {3 ^9 T      if ( FAILED( hr ) )   continue;3 R1 C: m. I0 b3 R% @2 z

! {* H' o8 @+ U/ u      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;. P3 q6 x. t7 A6 _  S, Y
     if ( !spBrowser )     continue;
3 _6 F! o! r8 M8 z  S" w$ [2 e. B7 p
     spDisp.Release();5 Q, b1 R7 j8 h8 k& g9 r$ ^& }
     hr = spBrowser->get_Document( &spDisp );
' u7 ^0 T: _8 O  w3 q0 z& n      if ( FAILED ( hr ) )  continue;0 I2 ^9 x/ U4 J! x; N! P: D

- o/ ^3 i- p9 T$ R" `      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
' o, u1 Q  d3 D' T3 X0 O- A      if ( !spDoc )         continue;" W9 R7 A; A4 S8 y$ C+ h1 d2 `* g2 \
* }, }2 Z& e1 j$ `5 v
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
8 f) u+ {* ^0 c4 C; ?. g   }
) \1 S/ J1 U. ~, P5 p}
  y, b5 k+ [6 d5 d
+ M' x! }( U2 P& U& J4 u( d  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
2 C# U6 w. E% ?/ h; {7 `9 L: Q4 `7 w2 Y9 c8 H$ k/ U! J' |; p

: P" k% o, X) y" k" f' Q. `#include < atlbase.h >2 y2 y7 K) H. |& r
#include < mshtml.h >
& c" B6 Q1 F9 d#include < oleacc.h >
1 ?, \5 I4 Q/ V#pragma comment ( lib, "oleacc" )5 @8 b% T; x$ m5 n- {

1 m* j5 k! e( f% H  f+ d( gBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)+ C3 @0 \+ @8 y+ l5 N  v  {! ?) }
{# F3 U/ C: d, C
  TCHAR szClassName[100];
2 L' Q2 T8 h2 {, Y& _8 ?) W! x% r
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
3 ~/ E' q% H& d- f  F   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )& u; }3 z) G. t3 Q
  {
$ x% d  S8 o: @" }      *(HWND*)lParam = hwnd;
; W: V9 g) h7 A* [' C      return FALSE;      // 找到第一个 IE 控件的子窗口就停止3 k' r: [* Q7 o4 ?& e
  }7 v, N# q' T! V+ `  |+ w
  else   return TRUE;      // 继续枚举子窗口
8 u$ A) @6 ^$ z9 b};
0 G( q% n5 B# Q2 [  C
; h9 g  a0 e! _, Jvoid FindFromHwnd(HWND hWnd)
) |/ t' Z% H$ `4 q{$ h: ?; a3 G6 g- f' A' I: o) b* d
  HWND hWndChild=NULL;
7 O2 }+ @% @# n6 d7 d" v2 T* C   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );' }' o4 }5 K- l; \; f2 v* Z! J
  if(NULL == hWndChild)   return;+ p0 e" z; z% m4 {, R
3 V- J# U* Y" n0 W( l
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );  U  X; A3 D$ t3 e- F/ N
  LRESULT lRes;
  i$ n8 y) a) z' B( ^: L   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );8 Z4 P( q  q7 k1 R! u5 f% g3 ^5 _, X
. i' q( i2 O# X* U* |) Z# p6 M
  CComPtr < IHTMLDocument2 > spDoc;
  }; {- z7 ?% s' T( g) E. a- A   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );5 d, k- l! `# c6 ?5 k& \! g5 b
  if ( FAILED ( hr ) )   return;" g0 f; y/ c2 x' [' ?  T
  S) m! }9 ^/ ~. ]1 m
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
  i7 Y4 k5 q+ a& M3 e) `}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 17:45 , Processed in 0.035311 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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