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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
" k! ?/ G) j7 T( S3 N2 ~" O7 B7 V$ o0 }  d3 s
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。3 h4 ^2 H% B+ L- d  R2 }: [
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。2 Y, _* C4 j0 }$ V
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
4 b  }7 Q, {, E" z        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。+ C7 }8 u% R2 R" n# a
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。2 ?$ u) ~* a. J& G1 L
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
, J( k- \  a6 ?. M) K( b3 c! n
# c) [* s' x0 h) K; eCComPtr < IOleContainer > spContainer;
( e0 T9 d) ~: U0 t* O% A- ^0 Mm_spClientSite->GetContainer( &spContainer );# a- o' C. O0 h1 x& J
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;* I" O/ V' U5 D/ c: J
if ( spDoc )$ O0 l5 N! I' f# J7 W
{
) Z# ?. {/ ~6 y1 q8 b5 ]     // 已经得到了 IHTMLDocument2 的接口指针
. d/ J1 y6 B6 q9 Q9 _" x& m! W}
& |& Q" z9 a2 x% A6 O
6 {3 S" P. R3 _7 h5 Z4 v" F  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。) B  Y  X0 k# \$ C5 T
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
2 b6 @' s" h$ S4 n' \  <5> IE 浏览器作为独立的进程正在运行。6 {; ~- b: N& {4 ?0 b9 z
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
! [" i1 {5 X, E& d0 b' p4 s$ s5 B3 ]% h% I
#include < atlbase.h >
' r. @( ?% e0 p  H1 `: O$ w' f#include < mshtml.h >& ]# V9 \) B# _
; r- g9 ?$ r) o0 l/ C
void FindFromShell()   }) _  z- @8 U# [" C2 K6 J: C( z
{8 a9 L( M3 Q5 O3 v! f, l
  CComPtr< IShellWindows > spShellWin;
- L7 j1 C$ }( @9 R4 B   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
; `4 e/ N. s% G# y5 V   if ( FAILED( hr ) )    return;) u/ _1 W& g. n( R0 {
* v  y3 M- Q  N& Q3 Z; d
  long nCount=0;
4 J" q8 @4 s7 J* ]: p) U; y   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数4 a, u) V+ i: ^! [( P" Z# c

# h6 F+ Y+ N5 k* |   for(long i=0; i<nCount; i++)
4 ]" R$ ?0 D& J       {
! _& h: N% M' D0 j& U9 s9 H4 e                CComPtr< IDispatch > spDisp;
" K; W6 Y' s/ `& x4 M9 C- Q      hr=spShellWin->Item(CComVariant( i ), &spDisp );4 N! v5 I/ |2 n2 U2 u- V6 m: }
     if ( FAILED( hr ) )   continue;
* `) n7 h( y; a) H! L1 R7 o8 x
+ R; u$ T' X  S9 O3 x8 F# z8 V& m, o      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;- t9 `2 c+ P3 _+ |. W7 f& U2 `. V
     if ( !spBrowser )     continue;
8 }* L0 N( Z& R% Q# j# V7 E- a2 t
     spDisp.Release();2 q& q7 P$ B. g) c1 z
     hr = spBrowser->get_Document( &spDisp );6 J( f9 j$ V6 z# D% e
     if ( FAILED ( hr ) )  continue;" _/ i, p( O+ M5 m& Z% w: I

9 [6 v( m% |. u1 _7 L, C# o" M      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;* I" W4 [3 ]8 y: K: _
     if ( !spDoc )         continue;8 f# K, W  B) @1 [# _0 e

& ?9 u8 b' b. D      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 e* E& ]4 C, E7 @: {2 E
  }
" K* u- q2 Y' `}
, ]( F% @# s& Q. S/ K) A! y, c  c0 e6 k; W5 o3 w
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
; d1 j/ q) L, n; t! Y# F. Z" P# `& k( o/ b" `) l4 u; x
" o. C0 O& o) s% Y
#include < atlbase.h >
6 K7 H# }) j1 S9 N9 L/ t#include < mshtml.h >
! i6 \- E# J5 v% v- B* H#include < oleacc.h >; K/ b& g" N5 z( z1 @
#pragma comment ( lib, "oleacc" )) H6 \# ^! E. n: Y; z
" y# ^  ?' q; j: {0 M" Z6 {$ z0 j
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
1 n/ i/ g4 Q0 a0 j% S; e" ?{+ S2 ?; j! Z+ G/ [/ _" }  m8 B; n
  TCHAR szClassName[100];5 g4 s& y/ Y' G2 R2 E( s$ g  R8 O

: _( U3 Q5 E9 R; t" ]& q5 @* Y3 W   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );- E: l1 w( i; a# ]! q
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )3 \2 L( a1 U- U: x9 J! J' W0 h4 u
  {: ~/ q0 j: l5 v3 F8 Z" ^. Q; D
     *(HWND*)lParam = hwnd;
$ K$ Y/ b( ^; K' \) u      return FALSE;      // 找到第一个 IE 控件的子窗口就停止/ r) U8 S! J& d3 M8 H4 l6 ?6 V
  }% S2 w/ G4 V8 |2 x
  else   return TRUE;      // 继续枚举子窗口3 Y. d) v+ [* o9 s* {, J' X
};, r( r, ?, L  [- T2 k, {

# H3 Y$ B! c) [: Y1 g5 |5 Ovoid FindFromHwnd(HWND hWnd)
* e, t7 B, C( L& O' [' M7 {{  D2 C( _3 m3 H6 e' U7 E6 K
  HWND hWndChild=NULL;
6 J0 ]$ _- `# q8 P$ I; h$ P   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
) d2 q& n% R! e$ j   if(NULL == hWndChild)   return;
- ?( G: \3 W* [6 [$ b2 w) K  A
- K* k$ i; g2 C, S- L, L   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
' i) y1 L. e' s! D   LRESULT lRes;
. l: ?* M. j. f! s( J7 O   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );6 X, S9 L* i% R& M% ]7 _' @

4 a& `6 W4 o& T8 A* _/ F2 z/ P5 f! C" T   CComPtr < IHTMLDocument2 > spDoc;
2 o9 n. N: w8 n3 K' s   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
/ l$ ]; R3 N  Y- K% O" W   if ( FAILED ( hr ) )   return;9 h& @/ ^% S6 O% K

) \2 v+ X8 }1 N. s   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针& ?& B2 c. E* |. g" h  Q) b
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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