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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
5 [6 Z! K. m. E4 G- {  J, {4 R6 b4 p. I- v" o1 c
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。0 @+ W% Z8 K4 k' |+ H& t6 g
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。9 S! N" C9 T" I
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
8 t7 }& F! M& v1 L        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
0 u1 M) b( P8 U$ S" W# O6 D- d  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。8 v. w* d' [: U, `
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: - a$ Z# d8 @. U1 O  ^
" i% U* d6 S+ x& r; {$ N; I  @5 M1 p: G
CComPtr < IOleContainer > spContainer;' t4 g0 [% U: L6 M2 ?/ q
m_spClientSite->GetContainer( &spContainer );
- R$ B% W# K; ?( `& x1 f( T' {CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
4 d. F% ?# L  O. ~if ( spDoc )
4 t) [7 w( X4 P$ m8 ^# o{7 D, U+ n( ~, B, Y
    // 已经得到了 IHTMLDocument2 的接口指针6 x! f& }2 N6 H, S; y6 [0 _
}
5 ~  s: k! f7 D( d- L( G) r1 L% v  w6 v( {2 o* l6 p
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
8 T) t6 J4 f9 Z* d0 v        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
* J1 i7 B7 l; O  <5> IE 浏览器作为独立的进程正在运行。" K) f& H9 W& C) I, R
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:2 y4 ?$ M7 h4 k2 Q; q
4 Q, ?8 }8 ]* @8 G2 u" T- t
#include < atlbase.h >
" Z! |; z+ {4 b+ P) u" a* Z- K#include < mshtml.h >
. E: O! I* d' `& t! U4 |. z- i7 C9 {2 L1 ^4 m
void FindFromShell() 5 ~6 N* y$ b4 G4 \, M2 |" x9 `& ~
{
, i  D6 |$ h& k( d! [9 [& {   CComPtr< IShellWindows > spShellWin;
  T, y: h4 w7 C4 g/ |5 a: \   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );0 e& F9 }/ }4 |: u$ v
  if ( FAILED( hr ) )    return;
0 L, ~3 s2 T1 |" @  Z% H8 U2 Q+ F6 z; @# P5 r4 w7 i* n) t. W" P
  long nCount=0;8 e# h! |: M' t0 o, A
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
4 E0 K& ?1 Y( K
( S" g( h% _- c; v   for(long i=0; i<nCount; i++)% A: A, Z; u' E" \7 z: O  X
      {
0 U& }5 }1 K7 e" H% C                CComPtr< IDispatch > spDisp;4 D0 u* H3 W4 n, x2 y1 n% k
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
% O( A+ m* F8 f, o" M1 B+ L      if ( FAILED( hr ) )   continue;( B( z0 V* T' x8 H

- O* O; Z. r" p7 ~) h1 V" |      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;6 J+ N4 v& k( R( y5 y* U' @
     if ( !spBrowser )     continue;5 ~  R8 }1 f3 K3 L
9 ~$ p# t/ M% r# k: A
     spDisp.Release();
0 E! v0 R  M) E4 y$ h: n' J' t& _      hr = spBrowser->get_Document( &spDisp );
0 H# {" C( C  L  N2 `( ?      if ( FAILED ( hr ) )  continue;3 x8 P# I! z: P$ r6 E9 y: [

8 }9 s" O6 b! L7 d7 w/ ~( k# E( `      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
) ^  J( Y; T; k% Z: S      if ( !spDoc )         continue;' ]" r6 h- u. w3 Z1 ?

2 ~" C% M7 a& R3 Q2 x: M. w! A- l. k9 H      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
, G- ^8 M  {+ C  L3 D* _& t5 E   }
' q) y/ h1 v: d}7 _1 t1 _6 g! z' [$ s, ?$ Z

+ H: k% D% o/ H+ `; M% y3 I/ ~8 n  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
+ b8 l; r9 Y' Z' y+ a+ c3 z2 |/ K; E; B6 U$ e
; T& `' w# U" A5 r" @
#include < atlbase.h >7 m/ U9 z& |* z1 O9 O7 ?- ]$ e
#include < mshtml.h >. C; s8 u4 d) a8 {
#include < oleacc.h >5 D/ I9 U! l6 r8 z
#pragma comment ( lib, "oleacc" )
: P% T, e: l+ e" ?. q8 S6 J& N$ Z4 ~; L5 P' J+ E& }- Z
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
6 |  ~) p. X7 c{
2 i: T. e- N7 X$ k" x4 G) B3 q   TCHAR szClassName[100];% q) t( J6 d1 t/ q" ]  M+ ]$ {

/ x5 W2 u$ L; }# u   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
; z6 b4 s* J. C: i- u) b   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )+ F; L6 Q6 ?3 F
  {
5 k' z5 `% Y5 k; M* R      *(HWND*)lParam = hwnd;
/ h# k/ _6 ]' W" f      return FALSE;      // 找到第一个 IE 控件的子窗口就停止# o- L( `8 P& u2 c- [
  }$ P9 O- K. f) x; S1 Y
  else   return TRUE;      // 继续枚举子窗口
# T7 A6 }6 K0 J& ?};
& Q6 @! z! B2 M" n6 W: C8 c
1 T  `; t- D, }9 l* q4 \: ~0 U0 p, Hvoid FindFromHwnd(HWND hWnd)
$ |5 J7 q( i: H{) i) F- T$ m) |9 l0 |& \2 P
  HWND hWndChild=NULL;
8 g# V/ Y9 s: x; C! u) T   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
% Q" ?+ ^+ r6 s0 h+ W; {3 F8 E   if(NULL == hWndChild)   return;" \- ~7 b6 ]4 S/ W2 F& s, h# h) @

1 j6 ^' l5 q) S, d+ |0 Y! j! d   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );9 a3 H7 S  \6 p5 M
  LRESULT lRes;4 \) _$ W& `9 v$ d% m
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
0 Z& y; w% e) w6 ]/ e# u' ^$ z. F( \4 M) U* s
  CComPtr < IHTMLDocument2 > spDoc;
5 J2 I7 K4 U  }( ?5 s8 g9 B( i3 p+ h1 q   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
6 z) K; {/ S: e$ ]# s+ I$ M   if ( FAILED ( hr ) )   return;, F- u0 ]- K- R2 w6 m

( ]' z: p* |; D" M% J   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
2 d# P) x$ u# B( p( Q* T8 ]2 s}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-13 23:52 , Processed in 0.017513 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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