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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
6 b. c' H0 c/ y: ]% F- l; c
+ _1 f% M5 ^4 F& g. I" b  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
, i' }  F" P/ Z- e0 L" O- ]% E        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
4 w8 W; J, ~: E) i, e  }  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
& k% \/ Y3 u& E4 s) _1 e/ K        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
" m, Q) i5 A+ Y/ `4 d  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。. A8 @. {4 E4 C4 D8 f
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
# A7 g& C9 }- p% F2 z3 I8 J8 A
' `2 r( ]) F; I9 n$ pCComPtr < IOleContainer > spContainer;
% q' H( W! z# u* R9 R: x* l2 V( e& jm_spClientSite->GetContainer( &spContainer );1 L9 v" F- \. O1 M9 |! U( y' @* D
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;7 C8 H5 s$ y. g: f& H4 L% M
if ( spDoc )
0 X& E4 j1 f. P6 S3 H{- J  s3 c  J7 {: V+ o7 G: }$ d/ L, \, V
    // 已经得到了 IHTMLDocument2 的接口指针
* Q7 O# k: R9 w" x* M# }' K}
% _# K& J! z. s1 s  q" D
- M! z3 e: u( w4 d: }  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
% ?4 _( q: a' H0 d        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
/ E) Y  J/ }2 V8 O  <5> IE 浏览器作为独立的进程正在运行。( t8 T8 Z% G7 ~4 {# N
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
. S6 M# F9 j4 N! _
! p+ B9 L/ s+ \" U( |8 F#include < atlbase.h >
5 p- P4 s( Z7 `/ s$ h+ L, `! [#include < mshtml.h >
$ y# k6 j" T& k* I! {6 J' G5 A' H& w/ |# {
void FindFromShell() 1 r+ D  ]9 f8 [  j5 E% O
{: i. R2 |: \2 q1 Y3 C! G
  CComPtr< IShellWindows > spShellWin;
5 e8 T1 x- u% ]   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
+ G) d6 l3 N' Z/ n   if ( FAILED( hr ) )    return;6 f. \& u! T* E# l; v
& z% x4 b" C) G8 [
  long nCount=0;0 v% t8 k/ w! P
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数1 ?! C' M; l3 Y$ d
9 a/ X4 r  _. C" E8 N! d
  for(long i=0; i<nCount; i++)6 \* `4 O( M* W* L9 e' r
      {( V5 a8 A- E/ ~0 c$ e/ h* F6 W
               CComPtr< IDispatch > spDisp;( Q7 C9 P6 [3 Z5 o8 o9 K) B
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
! |- ~* H' |: \% r& Y# f      if ( FAILED( hr ) )   continue;* @# c0 R7 r9 f! y

5 _) O0 h' S- c      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;. w; b7 j; O. d' k) X8 A& W
     if ( !spBrowser )     continue;+ F6 \! K9 |3 ^8 L) ]7 C' r: I6 ?
; F$ R7 c* C& B2 }  Y# B
     spDisp.Release();) {7 E! N% J3 k3 V+ d* l5 X! w: L+ e
     hr = spBrowser->get_Document( &spDisp );
! f* i6 _& _, M% p9 D, W  |      if ( FAILED ( hr ) )  continue;9 u' c7 y- e  ?* _

8 t8 V1 n1 n9 N      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
, H) g- i7 w; h% ~, L+ J; b      if ( !spDoc )         continue;
9 F/ Q2 K  g. F
' T( W- Y  p  Y% ~$ P+ f$ ?# d      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
4 D) M% D/ l7 U6 E$ l   }1 K) J' W7 _' F6 T$ c
}
+ @( ~2 v/ Q/ X, L2 O
7 t3 i) G" {& e0 Q: i3 O6 A  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 1 s" k& D5 J3 z% P1 r2 x

2 v4 {4 ?/ r& P- A8 P( V+ `0 ?- N) Q0 Z6 t$ t! g6 T
#include < atlbase.h >
; R( S6 [) d8 w2 P; A7 w#include < mshtml.h >' N9 W0 O4 m5 z  T
#include < oleacc.h >
7 s( v7 f" S0 e4 O& o- T#pragma comment ( lib, "oleacc" )5 O, Y: P9 O: _
' Y: j: p6 Q) W6 v$ Y
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)" u7 q8 j, z3 H" `
{5 r+ Y0 A9 i2 ^; S
  TCHAR szClassName[100];
4 h7 P: x+ r0 v0 N
5 _9 S6 S1 z7 Y, K   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
+ a( n! }6 E" T$ e2 g( \   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )" M% L! H; Y2 T1 f8 \( `( ]9 |
  {: H8 M  k5 @6 ]3 }% f/ z/ y0 q
     *(HWND*)lParam = hwnd;+ c9 i$ ^( J8 {; H  {
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止! F- O6 t5 t2 o$ C  y
  }
) z( f3 w& u7 j8 m   else   return TRUE;      // 继续枚举子窗口( j& ?; J; y7 x7 z
};" N- G0 z) b- X
! Q! A+ e. ?2 z% M& W5 g
void FindFromHwnd(HWND hWnd) ) M3 U- U  k5 Q' W
{
$ ]! T5 T- ^, s' @6 L   HWND hWndChild=NULL;
, a/ E& \: M% p$ r   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );1 M9 }: k: m- ]* X3 I: M  U8 O
  if(NULL == hWndChild)   return;6 L! F3 }8 J/ F$ D0 y* @
. p9 k4 q% Z5 C+ S. ^/ c
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
" C' i8 m" C3 i% e3 ?8 R1 w   LRESULT lRes;
: l/ r/ {/ n3 R) l0 F1 n% T   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
) q; K3 p* E7 d; S( E5 I
& [3 l4 V: C* ]1 B1 C   CComPtr < IHTMLDocument2 > spDoc;
3 ~" q( z2 p0 A- \6 f   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
& M" S; H' z  c   if ( FAILED ( hr ) )   return;
$ ]" ~6 {+ ~/ z" K
* B  V. H8 a% b' I# p6 G8 a   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 _9 O; |$ P; U
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-30 00:36 , Processed in 0.018621 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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