找回密码
 注册
查看: 4845|回复: 0

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。* `* |' I( ]: f! o" l

9 h! g( e8 \+ k- p$ h8 @$ x' X  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
! K* d3 B, K3 }0 Z6 A& q: n5 z        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
: ?9 W6 r5 d' {: U5 k* c  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。" u( Q) u: F# D( R9 T
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。9 Y  f- F: P/ n0 c# L
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
3 E3 B/ e6 S/ o# v- A& u        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: ( ~+ w* x* I3 L$ ~; N7 N: I  R
" s& J; I. e9 W
CComPtr < IOleContainer > spContainer;
% H  Z8 K7 A5 X5 @m_spClientSite->GetContainer( &spContainer );/ C- X" w8 z! W# V. k
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;, I* t1 O9 q# h  b, _; o! J
if ( spDoc )2 J2 k4 H4 f4 }
{
- s% [1 ]+ R. b- P6 D1 }     // 已经得到了 IHTMLDocument2 的接口指针
; h. R: D, q+ `}. _) X  a" o# n; |
( f6 A' Q2 O. ?1 ~7 H
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。! u. x; `  X( P
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。  l9 t1 o2 W5 x3 h
  <5> IE 浏览器作为独立的进程正在运行。
0 z" M- g* ?" _* f6 P        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:. W: X! S/ R1 y' v

) x1 c' g. t) x8 i4 ]' O#include < atlbase.h >
' w  r. t1 V- |+ K#include < mshtml.h >
' }+ \% U  e: e1 L$ v/ \
! W7 n+ B6 o* z0 o$ P5 z/ {8 `void FindFromShell()
4 q. ~. s6 Y5 ]2 l7 p5 L{
9 {# H' m4 i4 A: F. t  l   CComPtr< IShellWindows > spShellWin;
! |5 b* R0 w. L   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );) i+ r+ r( G) J
  if ( FAILED( hr ) )    return;
' e+ ?+ N( \/ R1 g7 N0 P1 `
$ b( E+ n: f: F' W8 u   long nCount=0;4 u3 J* M" U) c+ F4 r( f2 D& P9 d
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数7 I& N* c/ @: f

  ~8 g  d1 ?4 }1 T% Y   for(long i=0; i<nCount; i++)
, w9 W1 B* A+ U8 X4 k2 ^       {
) M6 p' h2 i9 x# k" S                CComPtr< IDispatch > spDisp;. `; q& D9 d3 {" L5 C' ~+ u
     hr=spShellWin->Item(CComVariant( i ), &spDisp );" r7 f! |/ W! |, T' R
     if ( FAILED( hr ) )   continue;3 L. W) i! y9 E) X7 R, ~# F  j
( e$ |3 z$ U" A1 Z7 W
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
7 ?# Z/ u$ A5 R- P8 b      if ( !spBrowser )     continue;, F4 J0 e3 F! E4 {1 W5 r( A
' {8 T9 S1 I" p" X
     spDisp.Release();
% C# }* K$ ~3 w* p: E      hr = spBrowser->get_Document( &spDisp );* i! K( A# B, w! c3 n
     if ( FAILED ( hr ) )  continue;
& {, b1 ?1 T( M' f6 c2 S' n/ z" n3 j
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
* \: e+ v8 \3 y% f/ q1 J      if ( !spDoc )         continue;4 ^% i/ V6 t% q8 c# \) m
. E6 L5 \/ r- r. @
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 T' Y  T/ X1 a0 w$ o7 ^$ ~* ]4 v/ p
  }. b6 G1 e1 c4 M
}
' G3 L) }1 x* _4 b/ `. m: O- L0 s' L( W/ O3 o0 a9 a
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
5 X& M! @0 y: P4 ]# @0 x! J% V+ R
- x# n8 ]% Q7 `9 N7 T
  J* @2 N% S, k' J/ u#include < atlbase.h >
5 ?% x) u/ o" i/ K# ~* a5 [#include < mshtml.h >
- }4 l3 X' L" r/ t- h# _#include < oleacc.h >' [& k1 ?9 v# W( }
#pragma comment ( lib, "oleacc" )1 j; p' |3 s, V- s, E

  t4 _+ Z; F( Y& B0 j% ZBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)3 c: i7 I; u! F  Z
{
/ l: {+ h/ t! C$ V. F   TCHAR szClassName[100];+ e; m9 j. B0 g- G1 _) j% O/ `7 ^" q

2 k  F8 q/ h" d% v; ~5 _7 h   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );4 {! I! \: \8 {( H, g: W
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
5 x: N$ G% a$ G( v2 |% R7 `2 t   {8 a! i# ~9 H7 ~3 p
     *(HWND*)lParam = hwnd;
1 h  J3 N3 H! ?% }' \      return FALSE;      // 找到第一个 IE 控件的子窗口就停止) n8 o. `. P& X( \
  }# B. @) `3 F- W5 T. T
  else   return TRUE;      // 继续枚举子窗口$ j3 y1 [6 X  J* x5 ?6 k4 q+ O
};, Y/ R0 y0 |" }, _
$ K6 B( T+ g: l
void FindFromHwnd(HWND hWnd) 7 K" u  R' Z7 S9 W7 a  y6 ^3 G0 X
{3 y- D# a/ g& W% T
  HWND hWndChild=NULL;
+ d6 L$ p$ Q. W$ A( }6 m   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );' m( {( u4 G( `3 n3 n. S9 A
  if(NULL == hWndChild)   return;
4 U0 v9 [. l0 a7 V+ V4 j( P6 z! k) P. k7 C1 ~( t/ _4 T
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
. I+ n2 K& K- p' y+ L   LRESULT lRes;
' K8 K  P, B& V   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );$ P3 Q5 u5 F! n- U& A, w
$ D: \0 V) l1 M8 p6 ?/ I
  CComPtr < IHTMLDocument2 > spDoc;/ o/ m5 Y/ G4 R0 c
  HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
2 U/ z5 n% V$ L1 W2 A   if ( FAILED ( hr ) )   return;% p2 s$ Y; o/ `! f2 I7 F
3 L6 g8 Q# [# O, U
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
% q2 V+ I5 ], @' u* l' m) }( g}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 22:02 , Processed in 0.021855 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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