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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
1 H, S" O2 F! T' o( H2 @% j0 z$ g1 V
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。. v4 f+ N  I; D5 _4 W) M
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。* r# g' x3 n8 {% X6 U. e
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
. J/ ^, n) p( s, b9 Y( z        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。! C& M* r. o0 V; z" l. Q' g
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。6 x. D) |4 z1 s* d5 Y* l# h
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: 7 ^- i  k# J/ _/ K( K+ F$ `- y# r

: F  b- \* ^4 M9 Z; LCComPtr < IOleContainer > spContainer;
* L  }3 r$ I# s! b( A, w, Tm_spClientSite->GetContainer( &spContainer );
; n+ w/ |' k3 N6 gCComQIPtr < IHTMLDocument2 > spDoc = spContainer;5 I! e8 W+ j: w" h# c2 V
if ( spDoc ). l# h2 Q# E) X; ?) I. u& c
{* t+ d5 u) @7 u4 {# t0 V9 _8 t
    // 已经得到了 IHTMLDocument2 的接口指针
- N, ~5 c$ }- ~8 K) Q}
* A: a( x, v1 E9 W
7 I5 ^1 Z1 B: a, }  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。+ E7 s! [& V+ U" D' V6 c( y
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。. S: Q. x9 a2 ?% x
  <5> IE 浏览器作为独立的进程正在运行。
. @4 Z, B( J% C) Y  v# ]7 {$ [: d        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:1 C! o/ D" k9 I
: N- O: R+ Q! f
#include < atlbase.h >
) P& M, T  u+ u# e; O" z4 J( `#include < mshtml.h >
8 M$ `3 i% k5 \
0 {+ @$ M( a5 m7 P& M1 f8 d% v& \void FindFromShell()
( c. v* r$ W" j# a{
; r! _- H+ y/ Y1 ?' R   CComPtr< IShellWindows > spShellWin;5 L- A+ J  C+ ]4 C( Q
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );6 G0 o0 R9 `1 l# U  u0 a1 d  h
  if ( FAILED( hr ) )    return;
, n( D+ z0 F# m/ R8 G6 {8 k1 \3 {6 H3 w+ T8 H
  long nCount=0;
1 e/ p4 o! j2 I& E; ^   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数5 H; G- z! _# U% M( C, f; ?8 \

6 [2 p! e# G. P2 g8 Y* S   for(long i=0; i<nCount; i++)! G: o6 h0 v6 V# u5 u% f7 t, r1 Q
      {* Q: h5 f0 Z" o' Q" u
               CComPtr< IDispatch > spDisp;
! k8 i( g  J2 ~; D      hr=spShellWin->Item(CComVariant( i ), &spDisp );0 J. e# V0 W3 f! K3 O
     if ( FAILED( hr ) )   continue;
: ?4 `! C6 ^% ~9 U  B( ?7 l  s' X: q0 h0 H, q2 g6 Z* X
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
$ I9 D# q: s3 K+ x      if ( !spBrowser )     continue;" t# q# L: ]  j9 I, u

; X2 X2 s* q, O7 [1 w$ |) G      spDisp.Release();5 V5 T3 A4 M$ l( u( L
     hr = spBrowser->get_Document( &spDisp );$ {- \+ x3 F2 q
     if ( FAILED ( hr ) )  continue;9 i9 z8 E" H& l* }8 ]

6 R  `" K' Q. m: h/ M1 P! V- f7 ~! r2 ^      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
7 u) r5 r" \- c: a      if ( !spDoc )         continue;
( R. M4 f8 Q, b$ V5 e' M
# p7 R7 R+ `9 H0 F, N8 G      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
/ ~/ O8 \2 P* b  W% k: a   }& m1 m: M) A7 l/ M
}3 z9 N% U6 h! {/ v
8 q$ S  M6 I- V, J6 m3 S
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 9 H$ e  s1 b2 ^" D9 z5 M5 [
) s& X, x7 G4 G

1 m; W- Q1 @+ V9 F+ Z, _; u#include < atlbase.h >
" h2 p: }" k, X7 u$ X#include < mshtml.h >
" {: F- U7 r. N# v' p- D#include < oleacc.h >
. k% Z9 h2 j! r. Q: d* U, @#pragma comment ( lib, "oleacc" )! Q4 l; C+ V+ j0 r

7 i" d* `4 s+ k  }# [  v$ C- wBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)" U& m" [) m+ v) ^
{) K, O6 _9 ]1 ?+ `, T" f$ b
  TCHAR szClassName[100];% ^/ C; G/ g8 ^$ g: d- {/ f/ ~' |

3 t- M7 x5 a' N% t+ H   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );  U& X( v3 M& J6 ]! m: J0 L' o$ P
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )- n+ I( D1 j0 j4 k5 m; M3 x& E
  {
/ g5 e( O( d+ g& Q4 K      *(HWND*)lParam = hwnd;" [5 e  t: C0 V2 X4 t) N
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止$ h" R/ e0 X9 K3 O6 ?+ L8 }
  }2 `3 |- i+ d! H/ v% b
  else   return TRUE;      // 继续枚举子窗口
5 V" z+ \! ?/ f+ }};9 ?& Q2 f& z+ u# f" G, `" O& b

6 ]% R- R4 W/ yvoid FindFromHwnd(HWND hWnd) " i5 y8 z. ]3 ^4 u
{& D1 W+ E! T0 x- d7 j' g. V$ \
  HWND hWndChild=NULL;
1 ^9 B2 _% J4 D/ i4 Z9 v   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
* v/ S1 e4 k* [7 S( t. \$ T$ z   if(NULL == hWndChild)   return;
! C; I/ O: _5 l: ?, s, A7 H7 `1 O" V  G* l
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
) `8 ~. w9 _# ]3 ^   LRESULT lRes;
8 a7 }9 H8 [7 R% K, {; v   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );$ T+ Z* ?1 P) i9 T" l) ~# M( [

5 }+ K) f; z7 X9 t   CComPtr < IHTMLDocument2 > spDoc;
4 H7 ]! F4 V/ c+ E6 A/ j   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );5 `8 g9 ^6 E# ?9 F. v8 [3 T
  if ( FAILED ( hr ) )   return;0 s4 S' w' i# K5 N% p, k' `7 D

! T, e, Z6 l: r/ @0 A   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
) ?4 N1 o# L2 f}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 06:49 , Processed in 0.018889 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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