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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
4 @& b+ W" @+ `9 G1 g: w7 H( i
1 [% ^& z, D/ B/ r! R  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
/ D& o# S" `) v- z5 p7 T! c- {        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
: D0 X* F  C" l! m  M" I. C  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。8 G% B9 [) q5 r& s  P
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。: O1 u5 G% K/ b" x1 M3 l
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
- T# X+ u) g$ B5 F+ i: m        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: ! }/ ~7 G1 W" e; r6 I! Q
7 \& S2 [  i6 K$ [. t( u
CComPtr < IOleContainer > spContainer;
8 N! k5 f7 Y( G" J! `  g, j1 wm_spClientSite->GetContainer( &spContainer );
# E8 u3 K, {* \+ u% JCComQIPtr < IHTMLDocument2 > spDoc = spContainer;
6 V# o+ r: X6 Z+ _6 l1 yif ( spDoc )- U; D6 m0 p8 s6 @0 |# A# j8 I
{
( W; U3 ^# n. `! _% O     // 已经得到了 IHTMLDocument2 的接口指针
# F; s( N- O, L, `}  T7 z( n" J' I/ I; \0 ^/ z

5 U+ X/ O: o( r6 [. i  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。2 l& a) e& ], o/ n# K
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
: F) W; C+ ?; j' E7 p" K  <5> IE 浏览器作为独立的进程正在运行。
; ^9 ?1 Z5 l  n: K        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
5 c& Y8 x9 E1 P
0 `" x/ ~1 B1 k! z  K#include < atlbase.h >9 A2 s  U3 b2 j9 m1 z; k( p! {
#include < mshtml.h >0 l; |' Z1 |6 ?
4 W: l$ i- d6 ]3 K
void FindFromShell()
1 ^/ o# e7 F# `5 Y/ a{
% \- T4 [. ]( _) M6 `, [   CComPtr< IShellWindows > spShellWin;1 r: O7 F* x& A
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );1 m+ ^4 N3 I. [( i/ B* I
  if ( FAILED( hr ) )    return;. q7 ]  }9 C) W3 m
2 \5 _. _# D9 D
  long nCount=0;
  Y) S  E) \( D! z" u* z   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
/ S+ q( l3 |( w# c5 P& f* e1 M6 }: M! L! e0 }
  for(long i=0; i<nCount; i++)
) E. B% C' d+ i* P' [$ k$ P' a       {
+ f. p5 X: o5 w                CComPtr< IDispatch > spDisp;/ {7 K, L  m- l% r. F
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
+ z+ l- e) E' f  R7 i      if ( FAILED( hr ) )   continue;
$ s/ g0 x$ f4 R! M' T2 z! g* k: |9 G7 p8 t1 {$ x
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;$ u) W1 c# o- r
     if ( !spBrowser )     continue;' O+ s: P- Y- R+ y

& d  ]1 U; R+ {* Y# _6 A, V      spDisp.Release();' ~! S% s& k1 A7 _7 {$ j6 g
     hr = spBrowser->get_Document( &spDisp );! P: u: \( o6 c
     if ( FAILED ( hr ) )  continue;
6 a! j1 E# p" G- t. t" t- ]+ K
3 Q/ r# _& b3 A5 j6 O8 v      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
9 S" }% |9 b2 w: C5 }4 d) Z6 `      if ( !spDoc )         continue;4 m. V0 P# }8 E& V6 q3 A3 M" I" t! C
5 X+ |5 {9 Y7 t. Q
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针( d$ Q2 a+ i1 E! R
  }% ?, L: a1 `% W9 L3 H; d
}
. W3 b. r, `* Y4 M* r$ d4 E4 }9 i) Q* S
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 7 r) `. P( B" U# I& R8 S

1 R' j+ q9 o! z( e; {9 o' p. v  s  A4 M9 ^- Y; {5 h% ~) S& Q2 t4 h3 \8 `# g
#include < atlbase.h >
* s$ `3 z3 {1 _4 z* A#include < mshtml.h >$ b# [: B$ d/ g1 `' _4 O( e
#include < oleacc.h >! w$ f- d* D$ y3 l. {* i
#pragma comment ( lib, "oleacc" )  \3 j: H8 ~3 s- |3 v' e

' c  [6 s" G- {; A1 P8 K! ~4 Q3 C2 iBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)- Y- O% m8 {/ t; t4 B* i3 P
{) B' @) C9 r, Q% S* J0 I6 n; K& o
  TCHAR szClassName[100];
+ k! Y+ ?( U& Z" }7 w0 O" k# D4 C' I, B
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
# B2 q- b/ |8 A   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 ): d* S5 w* g  G1 Z  g
  {0 A3 F- a/ t! L* F9 B% y8 c7 u
     *(HWND*)lParam = hwnd;6 E4 L7 j# Z& T6 P* `2 \
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止6 O  h4 D2 H. q% P# z! [& B# h
  }, Z) ]1 ]5 a7 L
  else   return TRUE;      // 继续枚举子窗口$ O0 {  i) S" O& w
};
, I' i$ C0 \9 m
! ]+ q: ?( G  p7 E. o7 a% ^void FindFromHwnd(HWND hWnd) 5 Z; r3 F! A3 h, v. i/ Y' H
{
8 W7 Q" v( I* b# l: N   HWND hWndChild=NULL;
' I" P6 w4 O) R) |& t. D% A& _0 e; i* d   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );/ Q6 x" R; {3 A$ l: Y% @
  if(NULL == hWndChild)   return;
6 F/ t+ i% y- V" \; \( ?1 Z0 y
0 k8 b* Y$ a% L7 e* r# \% {   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
4 i1 K, m% k5 l  V" i& \  B  K   LRESULT lRes;6 w3 x5 }5 Y5 ^0 n/ b/ l4 \
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );8 R% u' o6 \5 h2 N+ q8 x

& j, W' e9 d( K, i" r6 Z& D1 [   CComPtr < IHTMLDocument2 > spDoc;
: O- q. ]& R4 w  ]% N: q; ~   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );0 e* y3 L9 e8 s1 U: t6 ]
  if ( FAILED ( hr ) )   return;, Y% ^$ t: |7 W; `. X' ]

6 j# H$ r8 E4 E( _! H* |1 t5 ?   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 y0 |7 y! p: N9 v& ?0 b
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 09:06 , Processed in 0.035268 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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