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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。# c# t1 F! B! L- O
" I2 I+ P1 v* k. C% r0 N$ ~+ o
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。" t  f6 r6 T3 `7 p" V! `
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。. U+ d) V' e( `: d8 c
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
6 C) u5 D5 P: `: d        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
7 _- z& U: S$ W- c* [) y  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
- |) i6 L2 `8 }4 Y# [        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: : j% i8 O  L+ `' |. ~; c# F

6 J+ r5 H8 H' a  _9 gCComPtr < IOleContainer > spContainer;
# ~* i) M% C+ f+ }- x  I! k9 C) T$ Wm_spClientSite->GetContainer( &spContainer );, U7 Q8 s  Q% S' K+ N7 U
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
- W& K5 J1 i8 u; Q3 Fif ( spDoc )6 {& E4 \( _1 ]8 Y% N: R
{% T; r. I" N' j3 @+ t! [# \+ b; R
    // 已经得到了 IHTMLDocument2 的接口指针; S- i3 Y8 j2 b7 q
}6 A# m) I- b! K8 x9 S
. ?3 E0 q/ i% Z" @1 i3 P4 U
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
7 u; Y! @; \4 S' |! z% e        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& d1 O: c( |: c9 Z5 ?2 Y* ~) C  <5> IE 浏览器作为独立的进程正在运行。! |! i3 w2 g- a/ _4 N* F
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:) X: A, ?' [/ k/ Q. ^7 ?

# e# q9 Q" Z; h  k#include < atlbase.h >8 M2 X" h- X/ H2 u& B. ~; z: V9 L
#include < mshtml.h >
% _0 x4 o" V8 y" ~) J
/ z9 ~/ t5 x' |( i" X: R) bvoid FindFromShell() + k1 l7 e$ `" o* K* @
{
; c& N  u4 ^$ S5 I* q9 z   CComPtr< IShellWindows > spShellWin;
$ j0 U: N/ ~4 f! ]8 j" {1 l   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
6 j0 U4 a) k* j& ]: X8 a1 c8 m   if ( FAILED( hr ) )    return;
2 W  a7 B. T+ Y: B5 C! L- z. f) r0 B# |1 u. y3 n& x
  long nCount=0;
$ N7 y7 k& W" b( J   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
% M; I' m% G( ^; e3 u3 w9 F+ f8 g1 i) [
  for(long i=0; i<nCount; i++); w0 O% ^4 z" w" R" h
      {) ^- x% ]+ m& [
               CComPtr< IDispatch > spDisp;. K1 f0 J+ F& w! G6 s* B! }1 {; r
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
& ^8 {+ ?6 [! U% Z      if ( FAILED( hr ) )   continue;. [5 G* b7 Z& a, }
( `( X6 o- \5 k- ^4 s
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
2 ?) k2 E; P4 N4 T: ^      if ( !spBrowser )     continue;  L/ F! a, O8 u) ~6 t3 g7 T
% X$ I6 P6 Q5 G' Z$ u) a0 q
     spDisp.Release();
$ w/ W% s& u, }( ~! v      hr = spBrowser->get_Document( &spDisp );
2 ^3 \/ i" p: t7 ~      if ( FAILED ( hr ) )  continue;
( W& e9 o# s* @9 ]5 I' Y/ n: O' a) P$ b2 K! C' R( j- O9 y1 M
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
/ T2 p0 J; S# Z9 F      if ( !spDoc )         continue;
( ?4 n2 ?. {) ^4 t& x8 a' L: `
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针+ R: a: @0 k: w/ \8 J! \- E
  }4 c+ p! i9 t' y3 t( J
}
4 d& z. Y; C1 }' a$ r7 r- m: g9 ?7 r
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: + s' x8 s' ^  E" W; g  ?4 x
. k' ~' f' s, b$ T5 R: K
0 x: A; b# G6 i3 n* n2 |
#include < atlbase.h >' o3 ^& Y# g" d  B  I
#include < mshtml.h >
9 `  G) M$ C& ?+ k% [( T#include < oleacc.h >% m# u+ x: @0 D
#pragma comment ( lib, "oleacc" )! B: O/ l9 o% e! j  l1 ~$ {4 W

2 C* H* F$ f+ Q  n/ |( _BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
8 O& R# e+ s, q3 X- Y2 Z{
, D8 W1 Y+ P/ h  Y7 Y8 z# C) d. v   TCHAR szClassName[100];* v* R7 y  T3 k$ r' f) m
$ T8 n( G' n" C; R- [! f. Q8 B
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );' J' N7 V7 [  Q3 f2 D8 ^
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 ). [; P- \6 B  ]6 t
  {( l  r/ `) W. C; x# G$ q8 C
     *(HWND*)lParam = hwnd;* [: d$ p* N$ }
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止0 d+ V8 p& B9 I+ G6 {# o/ F9 G( \
  }
  H) J) s( g, X) a5 P$ u   else   return TRUE;      // 继续枚举子窗口
9 I$ [) I, L. k5 k$ K; R" s! `};3 x$ h; L, e3 C4 h

8 ?& ?4 X0 E4 q( ]: x/ N) cvoid FindFromHwnd(HWND hWnd)
& t  N0 |+ n7 c% V8 t' T$ H{
+ O$ q- u3 T6 F4 B! t   HWND hWndChild=NULL;! ]4 W" C, d. S8 ?! \5 O
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
$ C% i2 t6 b! V# ^# U7 ~   if(NULL == hWndChild)   return;. H% T6 [( v& U- e9 s+ d

  }' Z. M' H  V% E8 Y5 g   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
% z0 w% P- @2 l' P) R" L8 m7 q1 Q' c   LRESULT lRes;7 {( X9 j% g) e* _4 O4 F
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );/ }; n( g) R& L: v0 T6 j; @

+ r4 U; v% n2 h: q; u/ v$ ~" G. R! G   CComPtr < IHTMLDocument2 > spDoc;
( a1 h; j7 h# f3 C   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );5 A8 V3 [2 O9 O/ Q
  if ( FAILED ( hr ) )   return;1 f' `$ m7 r; `
, T% j5 ~2 U% {' `- \* C
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针; F, B3 g% L0 O+ u" y$ f
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 23:15 , Processed in 0.016119 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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