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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
9 l. i! B8 W& _, j7 ^7 b1 ^
. M& ~- {6 |* a* g- t% o  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
$ ]2 o' y3 o! `1 ]        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
4 F9 H1 ]$ q' k, Y3 r1 h  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。/ u9 r+ b( o* j  s7 o5 }
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。+ Y0 a8 T3 d8 C4 g) ?$ Y2 s
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
; a; B% F  K! b% D/ L! N" E1 J        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: 5 y( r$ l# [( F9 K
8 ^7 `7 ?# p  }" A2 b
CComPtr < IOleContainer > spContainer;
; x8 G9 f8 n. c" q" w- P7 {# Y- Zm_spClientSite->GetContainer( &spContainer );
( Z5 O$ |1 m9 k6 [0 ?9 D$ OCComQIPtr < IHTMLDocument2 > spDoc = spContainer;% ]! l- I& Z5 F" C2 N7 J9 u
if ( spDoc )4 R2 g3 W- f: ]3 c, O
{
( h& f, ~# m! ]" ?     // 已经得到了 IHTMLDocument2 的接口指针8 U/ i& ?  p% B5 h6 {: `
}
0 @( Q# b. U( k7 q. C2 c
" x' C9 O" C; H/ J- A! Q7 b4 h  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。. d6 r0 a# _! q7 l+ H) W3 s
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
0 E# J7 ~& |( Q9 k3 E0 i3 a. Q  <5> IE 浏览器作为独立的进程正在运行。
3 E( ~  s+ Y# [) N3 g( s        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
" u: z1 ]9 |/ ]" ?: E+ B5 N8 p( e
#include < atlbase.h >, V. F, G, O4 p( P; [/ e
#include < mshtml.h >
! N6 L% p% O2 p- N  n) G+ D( R' V5 M; }
void FindFromShell()
: t7 i% E  W2 W* k) m9 H, S{
; t/ F, m2 \3 N: e# [( e   CComPtr< IShellWindows > spShellWin;- O6 [3 T+ q. z1 C4 h* K
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
: N8 @$ I% q- H+ t" ~" S( Z- _& T   if ( FAILED( hr ) )    return;1 k! P1 Z1 g3 d' B0 |0 r
- O( ~- Y% f  m0 J' p
  long nCount=0;
% Z5 q( e" N( m7 e8 W+ K( i/ U   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
" l4 E, O% B$ X' D
$ _! }+ I+ T7 O3 K6 I   for(long i=0; i<nCount; i++)
3 L" r3 w& M$ D1 Z  V9 |1 v       {
0 N& q  {8 T& j& ~                CComPtr< IDispatch > spDisp;
; ]# I4 {0 ~% I5 H( P      hr=spShellWin->Item(CComVariant( i ), &spDisp );; u/ w- i4 M3 n! J% A. h4 |
     if ( FAILED( hr ) )   continue;
& j! q' T* V$ f6 B3 a
% ^  l8 |% M# G2 \  T0 N      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;5 s) N5 q7 h! ?$ Q" A0 D
     if ( !spBrowser )     continue;
2 A, E6 Z* `4 b- U; Z! A& n% ?9 C5 O3 b
     spDisp.Release();
( G6 I1 w) _. G# k. z      hr = spBrowser->get_Document( &spDisp );
, r4 f; [8 j: [1 w/ T) |, T" M: \! a      if ( FAILED ( hr ) )  continue;
4 _. y/ O# D* ?$ V4 ~; n# O& S( b5 w) H$ a
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
) _* O* ?; n9 t1 c7 n* y6 G      if ( !spDoc )         continue;
; T3 S1 p  ~) U1 P3 `# E# j& O( T
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
2 m: S; q$ @8 b9 ^" @3 g7 O" F   }8 k# V. e* W! F6 R
}
! b+ z0 H0 g3 D( K' {1 o' L- @, ^; y
2 ~5 E) E+ c3 q; e3 o' `4 G  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
; o6 ~/ ~0 I7 c$ f, A& @" s/ }# l5 l5 k1 j

: H% a0 T. ~% i/ I; x: z3 D#include < atlbase.h >
, C/ Y& I, ^( j2 D0 W: @- ]#include < mshtml.h >
; x1 z9 q* ~# j5 G3 Z$ }#include < oleacc.h >
. W( l; Q+ w! B5 I5 v' h) o+ T#pragma comment ( lib, "oleacc" ); J* j+ U  Z4 g6 f, D- R$ r+ ^" ?
5 r( R+ v7 r0 j% f" O9 a2 y7 U+ z
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
. ^7 d6 t' n' \$ S& d- E# }& d* i. d{
1 ~3 [1 R0 f+ j+ ]' z4 G   TCHAR szClassName[100];2 c4 n$ t0 C) M$ a
3 h( O. u2 [6 `
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );# G* v% L, T  A
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
' i9 w7 v* H! ^* w+ G$ r6 V  ^- A   {- q. }% ^) i* s/ N/ C6 E
     *(HWND*)lParam = hwnd;
) L; P% Y. _( e0 I      return FALSE;      // 找到第一个 IE 控件的子窗口就停止* V# C  N: F6 b$ ^. {: o) {5 W: B
  }
1 g1 `* |! P- \+ h   else   return TRUE;      // 继续枚举子窗口
3 R  ?' k  l0 x! U7 O( Y4 g4 L};
/ U6 u$ ?/ R; u9 V7 i8 N! i: N6 Y0 C" `5 q: i+ ]
void FindFromHwnd(HWND hWnd) 7 J% M) D  H1 ^1 Q) A' H/ K
{9 H7 z3 z6 V  Y: S5 @
  HWND hWndChild=NULL;
- ~$ S" Z8 G9 X9 L( W   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );+ F' }1 k1 z6 p$ D5 D. ^
  if(NULL == hWndChild)   return;! n: [8 Z/ v8 ?: z7 E+ Z: V

1 o" A/ @2 ?6 J% `7 G9 d   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
& E7 a: M" e! O6 L   LRESULT lRes;
' ^4 w( A/ r) S% @( |3 f   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );4 b. [  Z1 n# F6 S. n
9 {% L% i' H2 q3 j+ n
  CComPtr < IHTMLDocument2 > spDoc;
1 S* M# x7 ~6 a   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );3 K- z# Y( `, ]4 O9 g& X# j
  if ( FAILED ( hr ) )   return;, D/ h  R. S0 t( T' C0 D- F% v

" \5 e0 w. F' W" ?( F$ x   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针' v1 C6 ^# y3 h# u5 Z4 Z- ]
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-29 22:19 , Processed in 0.019179 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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