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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。9 M  }; N9 B6 q" R; ~4 U9 w

4 |; D' x5 V: J/ @/ J* U# t3 y  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
. N$ M, o% @# D3 F8 t2 U5 y7 U% Q        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。2 n- |9 W" G) R; N3 y7 z1 F
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
0 v3 Z) m6 ^! S( p  ]  M. o2 h        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
0 G1 @; o: Y* ?. u5 P% h# w$ k+ P  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
0 u/ A: }' s. q8 h6 ]' ^        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: " H& W4 r: D0 J+ g% `2 `( C$ b& |
3 a% W/ R5 c8 x) ]0 F. \# y
CComPtr < IOleContainer > spContainer;
6 q+ A, D1 p0 Q0 Im_spClientSite->GetContainer( &spContainer );0 J3 P+ e5 Z+ H0 {7 k$ z. _
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
% e( O" Z, X+ d( O# `6 z% ~, u& jif ( spDoc ). k' b& y( q" [( `% s
{
/ m) L7 w- Y1 S" N" L3 J     // 已经得到了 IHTMLDocument2 的接口指针
5 p, L0 C' a) v, e4 q$ N; `" {}, v% l# w* L8 x+ H- x' H

; f' X, x5 R% h9 z  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。" ?9 I& z# g' ~" Z2 {' b( W
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& c% E, j! E) j8 K# D: m  <5> IE 浏览器作为独立的进程正在运行。7 K. @/ F: u" I! C
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
' N) p1 ^. g5 T0 j$ x! I+ n1 i* G; J* |" F( D! W$ k2 J
#include < atlbase.h >' l3 s. x# K, @: C
#include < mshtml.h >
) d  Y, d6 f9 B& d' F# G# a6 M
7 q0 B: p( s. g% ]- ovoid FindFromShell() 7 D  H, @( k/ H
{& l1 |3 k: P0 q( F- w
  CComPtr< IShellWindows > spShellWin;
5 z# d( e+ E$ r+ H, q8 a4 [4 t   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
2 Z9 w1 i, y8 Z# I* [; x. ?   if ( FAILED( hr ) )    return;
/ S: E) t! i1 V6 }4 Y
& q" T0 S* Q9 ^4 g$ I   long nCount=0;
% T, D% T" Y3 C# V   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
! {* L2 T6 u% ?/ l7 h  C& o+ m
: h9 y% q; v, k0 |4 n. Y* h/ e0 d   for(long i=0; i<nCount; i++)
1 T: ~" r8 {2 ~, [; |1 U/ @9 w3 I       {. e  j, m; q/ A% W
               CComPtr< IDispatch > spDisp;! q0 F: l  m3 K, N' w, i
     hr=spShellWin->Item(CComVariant( i ), &spDisp );( Z) F- _) D4 ^
     if ( FAILED( hr ) )   continue;
7 r% D: ^8 ?  ~& a, G+ X. J9 e# A4 B0 j/ }! \
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
* i7 I% r2 i& o3 o* [  f      if ( !spBrowser )     continue;. ~6 }! J+ k; m6 _* K  W. M( ]" Q

3 l/ N6 [# ~3 x# B7 w! B      spDisp.Release();9 |( B5 c+ d4 @  e7 q! w/ @$ _
     hr = spBrowser->get_Document( &spDisp );% \$ Y- ?" w6 Y8 D
     if ( FAILED ( hr ) )  continue;
8 [% ?/ w1 c1 c; h7 _
: q$ S* W% w4 [4 T% C9 J6 w; e  n      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;1 S/ |9 L: Q, W/ k
     if ( !spDoc )         continue;
# h; F# e- k2 p5 v9 A7 \: j) Y# e; g4 D8 }: N0 ?4 i  h
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
* n8 C, _! u' i3 q' A% `) t1 [3 h  ~1 g   }
) H5 O0 I" R) |" k" O}- \) X* x5 S  p6 M4 Y

; o3 F) P9 }( @- r9 P; L% Y" Y0 I  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 1 S1 q/ `2 m; |9 v0 g
( ^. F6 {. J/ ?& v- M0 A+ r4 F

  i  {6 A5 b* `0 q2 E0 R& K2 u3 K#include < atlbase.h >
3 m" \& H  U. t, A' L. _#include < mshtml.h >
: F+ A. m; E7 H. d4 [#include < oleacc.h >- B1 p' i; D8 c4 G
#pragma comment ( lib, "oleacc" )
) A/ U$ D- W- c3 W% F8 R
# i/ ~* _8 j2 E8 O- lBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)+ V  ?# O" E" p
{
7 a( R" w7 Y& g$ K   TCHAR szClassName[100];- K1 R6 C0 M; |( Y4 D0 C
# h+ a  ?6 ~. Z" u" \
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );  L/ K/ {1 c1 I  d5 Z
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )8 }+ p! N6 B& z6 i$ H( x
  {5 n, u7 L( C) p( A
     *(HWND*)lParam = hwnd;
' N8 N4 H3 v6 s7 K. C      return FALSE;      // 找到第一个 IE 控件的子窗口就停止
7 K9 o* _6 {' ^1 N$ B" R   }
9 {" `( j% w5 F0 m' _7 r   else   return TRUE;      // 继续枚举子窗口7 S* a; e+ m6 U9 ]# I
};
8 Q" _4 W: R8 j$ H( c8 u" z& T5 p( _7 p/ t7 E
void FindFromHwnd(HWND hWnd) ( o% I% o) w( ]
{& u+ W$ \& O; C- }
  HWND hWndChild=NULL;
. `, x! m6 q. g. O% {2 Q   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
! u8 T7 g( B2 X3 G' P  Y5 ?7 V   if(NULL == hWndChild)   return;
1 Q: r7 @) z% x7 w3 m, [; d; \+ s; D6 l7 F8 [( x
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
. \: `  Q" ^0 H( N$ \0 A! B4 J   LRESULT lRes;5 _* l  _) t# v* W" M; M
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );# h5 J+ o& ], Q8 s( q
7 O9 E5 r. O, p8 R8 A
  CComPtr < IHTMLDocument2 > spDoc;
; A2 |6 g$ \, F: v! f0 U( u   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );  U1 O, m8 T& d" C0 K  }
  if ( FAILED ( hr ) )   return;
3 W( q6 l1 j& g+ x1 q3 L/ W% h( [# b" I% ?, b
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
" g0 Y4 x4 w' ^2 g% G8 ^/ a}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-5 08:32 , Processed in 0.014719 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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