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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
4 M: V" x  s2 {) E7 K% W  U* N
2 y$ b, Y0 G- \* I, Y) ]! m8 N  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。" K8 W. o( Z5 i3 n& Y- n
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。& L, l* r$ F) r6 p# i6 f: I/ M
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
& ?) }8 K# W# \6 B( j        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
5 G, V# y' q, \5 ^  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
6 E8 V  m. H- G1 k+ R1 G        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
; _9 N8 T& I* b# P9 D6 c4 O- I) y1 O3 U( s( R/ K
CComPtr < IOleContainer > spContainer;0 z; ^) n  }4 J" S% [
m_spClientSite->GetContainer( &spContainer );
6 `, s. n* y. H) Y' I6 GCComQIPtr < IHTMLDocument2 > spDoc = spContainer;" T$ D" N6 d" u: U0 O5 s5 m$ W
if ( spDoc )9 W0 X- {8 ]+ G0 }" w" ^! @
{6 K7 p5 u+ F; a' F! H0 c3 _" D
    // 已经得到了 IHTMLDocument2 的接口指针" m. D/ h4 V. _6 {
}6 z- H$ O/ w0 }

+ X$ p0 e, P0 {7 Y$ `* E  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
* L5 \3 V  D+ \: ^        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。# S4 f6 e! p' [$ c- p6 Y
  <5> IE 浏览器作为独立的进程正在运行。
2 Q' F- D7 E# x. M        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:9 S* i  |( F8 `
) }/ D5 }" \' s5 |  _2 N
#include < atlbase.h >$ d4 a) ~9 x$ F* [
#include < mshtml.h >9 P* Z% S9 ^1 V) J) U5 ]

. G" @8 |$ t' k; @+ E9 X3 ovoid FindFromShell() ( n5 a8 V, T" p# Q5 O  Q
{
- z1 U, F7 ^- [6 z# C# |+ \   CComPtr< IShellWindows > spShellWin;
/ W1 c! r  |' [+ {   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );1 {2 I" Q% {. p  \1 T, z
  if ( FAILED( hr ) )    return;
5 E( H- P, `! k, F
3 ?# q7 ~- ]6 ]; o+ s& D7 l   long nCount=0;; F, v. G6 J. v4 q4 L
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数9 @/ q# n3 ~9 z2 t$ L5 [

2 E) S8 R7 W: ~4 ~   for(long i=0; i<nCount; i++)
6 j% ]+ E7 l2 N6 N! T       {
9 ~) i0 U+ E9 Q                CComPtr< IDispatch > spDisp;
  U9 D' J5 R2 a0 ^5 K1 U/ j" h7 F      hr=spShellWin->Item(CComVariant( i ), &spDisp );
" I# \! l% j* _9 k* S6 q+ b      if ( FAILED( hr ) )   continue;9 s" H4 ?4 `, E

+ q3 W# _( h8 S# }) i( ~2 c' U      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
9 y0 n0 k" b( n$ J" w      if ( !spBrowser )     continue;/ X8 {0 `/ z$ a- u. _

7 W, x: h2 d, N2 G* Y      spDisp.Release();
5 ?) X: D" j6 r* e1 R      hr = spBrowser->get_Document( &spDisp );
% m, R; Z, X5 m6 g! y9 i      if ( FAILED ( hr ) )  continue;. n9 X2 `8 }/ A7 ?
/ f0 G  ~# [/ Z0 x# P
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;! P5 z, t0 X9 p- j. W1 ?
     if ( !spDoc )         continue;" O0 I" S; o, f" e' U; p
) w% f6 _( G% N+ C) x+ J
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针% B# @/ A  F2 k+ n8 m' `
  }
: j+ x4 V1 Q5 C  w}  T1 z3 m3 ^! \6 V* D% b& o( p

. @: e9 v& N8 A. i$ m  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
( {& }2 Z) f" w; {( \
# |2 g- H. g8 S
% D1 ~5 A, Y; e2 [% y, Q#include < atlbase.h >$ n4 p! _% x+ V; C
#include < mshtml.h >+ Q' q( t9 c/ Z/ T1 F# _$ s1 A  B
#include < oleacc.h >
6 `% u- P( F' I#pragma comment ( lib, "oleacc" )
' p. j- `5 G) R* r3 b; }( b" R# j3 v6 z) P  C6 y6 Q4 V/ N
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
4 o7 c; L$ c* o, w+ X3 d{
  [- K: H5 d+ A# M   TCHAR szClassName[100];" y+ n7 r/ ~* k2 z

6 v1 m) O/ z! ?, ?   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );! ?, e7 `- z4 |* T) b# W; h
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
3 ]# G, x, |) e/ F5 d- V* a5 I' {   {
+ H: D/ g4 G/ G9 v7 a' G      *(HWND*)lParam = hwnd;
  o6 t6 M- t7 I" B3 A      return FALSE;      // 找到第一个 IE 控件的子窗口就停止
+ G/ M& `* _5 d- F5 U" ?. I   }$ P; V2 b. E1 \% W
  else   return TRUE;      // 继续枚举子窗口
. k4 P2 M2 M% I9 b};# k8 J$ E* w- g8 ^9 m
8 D$ D. {5 M, o' q
void FindFromHwnd(HWND hWnd) & b3 E6 h, k4 X  K# Q2 P
{
( `5 U- Q) K  u6 i2 Y" P   HWND hWndChild=NULL;
  R6 ~; e7 P6 o3 [# c. }6 W   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
+ V2 W$ g0 x- i9 |; N0 n   if(NULL == hWndChild)   return;1 R4 Y$ f& G6 `$ V  ]2 E. i- U

1 u* s$ F) p: u9 Z( p   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );5 f: s( L% ]: k' T/ r0 [
  LRESULT lRes;
9 q* Q9 ]( m. ^/ K$ \, p8 q  i1 X5 j   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
! v" N  a$ z! t  @4 g
9 j8 ^4 C0 H& D2 x+ w6 h! p   CComPtr < IHTMLDocument2 > spDoc;
, T; c, ^: k  ^6 Y0 ?- N# ^  E9 C0 I8 `   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
& d* q! i- I. @% [0 h   if ( FAILED ( hr ) )   return;
3 w; M( R' p5 e; n  y  K+ I- f5 p5 r, S/ ~2 C( K$ K1 J. c
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针1 m: I$ X8 G8 P. d, @
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 11:51 , Processed in 0.018997 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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