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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
$ K" C7 }" Z* o) [% U: `
2 Y2 d/ f* F' W2 V  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
# H) `7 Y- b5 k        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
( ~, K* J, w. u% j" U; S, V2 m7 D  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。  l$ _" [- ?; b0 ?) @) v% z
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
4 X$ K3 `2 |- }# A  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
( o0 T  F+ p# N9 y        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: ; N( J8 N6 T2 ~4 _3 i

9 C+ Z& N7 Y: v+ BCComPtr < IOleContainer > spContainer;
& g5 A. g6 q, p3 l  j  e+ Gm_spClientSite->GetContainer( &spContainer );9 w" J0 b" H* `/ h8 a7 {
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;* P( _' C' a0 g) `
if ( spDoc )
* s7 `9 f+ O( C; o{
5 q: x6 O4 f* |     // 已经得到了 IHTMLDocument2 的接口指针
& q8 g1 u1 \. O4 v  s$ l}) S2 K5 t" m& w" @
; J, f$ W9 W' w; R' i5 {5 Y
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。* q0 q- d# _) |1 x2 d- B
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。3 w6 b/ @: x9 r" c
  <5> IE 浏览器作为独立的进程正在运行。
% I2 i- m  z, z. G        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
+ J$ g7 s  o  ~* `" @4 O: `6 g, {6 g
9 z" [$ P0 T, L4 s2 [#include < atlbase.h >; C1 y8 h: `1 ?* T, i! i7 v2 h6 @
#include < mshtml.h >
. N, V/ e5 ~3 \* h! X6 E, z% ]* w$ @3 P7 u" X
void FindFromShell()
1 z! W( {* h" q' Q0 e" j7 ]{( Z2 z3 t5 ?) n
  CComPtr< IShellWindows > spShellWin;1 r( ?/ z. n9 n) [; X
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
# P! C/ m7 |+ f1 x7 `# a, I7 E   if ( FAILED( hr ) )    return;
) I. r  Y6 @4 |2 X. s5 Q- h3 _" ?1 C, A$ O  w. W2 Y
  long nCount=0;
: N% E! E  d8 Z8 e* s   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
9 q4 H+ {& p7 H0 `6 n* M8 E
- K: ~; _3 j* }3 n) Q7 M' t   for(long i=0; i<nCount; i++)
5 n" A( G& Y- }) F       {
, @% h, z6 w+ J3 q: g! ?. V1 ]  T                CComPtr< IDispatch > spDisp;' `; X9 m4 T$ F5 u# Q2 `/ V
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
4 F4 j9 U8 I+ E* L3 E% }      if ( FAILED( hr ) )   continue;
$ d2 C& K% q' P/ `3 N: h/ b9 h" T$ n. r# r
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;3 h2 ?8 ^, D, m2 H6 ]7 j
     if ( !spBrowser )     continue;
& G) U# O6 B( R( l5 Z7 r
/ t2 I2 D' W+ s3 y) i6 F      spDisp.Release();
5 x% U8 M; q+ \$ k      hr = spBrowser->get_Document( &spDisp );
$ E+ X* ~; p" V2 P6 B      if ( FAILED ( hr ) )  continue;, t1 o2 t7 v3 }& w5 v5 m1 S
$ r* e7 U" k, O3 a
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
1 l1 x/ v% j7 x+ E0 U+ \& @0 I8 R      if ( !spDoc )         continue;4 o9 s0 R/ Q' h" h

, o8 D: r  p4 S      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
, u6 K6 G- x- c) z8 E   }
3 D& y& J- H7 e" d/ s" I}
( D  k/ ~5 h5 W- M" W! z
+ Q. m) O$ s$ d  E+ h# }  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
) J. J2 t  z- `
8 J( v. p! O3 d' t
! z' \$ Z# ]7 e- Z/ O#include < atlbase.h >
* a/ M. ]! z  t: e' \#include < mshtml.h >: I' x* W" n0 O6 k5 v# x' i1 M0 ^, H
#include < oleacc.h >
7 Z" N% f. l: q  D0 D4 x, X#pragma comment ( lib, "oleacc" )
* W9 R( i, F, d# ~, g( i! i+ T; i9 N5 M
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)( v, m5 y* Z& \
{
* O% P! v( f, Z6 K- T$ \$ {   TCHAR szClassName[100];$ [7 T3 K2 r4 Q( Q9 z; b
: g1 @9 h/ v; i6 Q" n
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );! o$ z0 b6 \# A1 e5 M, V! R
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )$ G- y: w! V# y# B" A# r8 B
  {6 |, G* S7 H/ S
     *(HWND*)lParam = hwnd;  ~4 N! K7 U  O0 `% ~
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止8 `; [* u' ?+ p5 [2 |2 E
  }
" I1 M5 H  F; C) I' j' M7 M: h3 ^   else   return TRUE;      // 继续枚举子窗口
7 Z: w0 E( x; n7 a6 d1 [};
7 @" u. h0 m0 J/ ~, r5 v( Y5 W$ i0 [; ~, |: e! u+ X3 k1 T/ T
void FindFromHwnd(HWND hWnd) ( w6 L4 Z6 p1 U& R9 J
{9 d2 t* O5 u( b" T, s) Q1 W
  HWND hWndChild=NULL;
6 a& |' U+ @+ n. i& a   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
7 Z3 z8 s( y* n   if(NULL == hWndChild)   return;
+ ?) {+ E! b$ L3 f4 V$ x5 U* O/ [$ e3 u7 z, D
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
. T6 j5 j' i% p$ F% B   LRESULT lRes;; K1 y# l; J* V/ d) E2 Z
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
) X2 \9 T/ L0 `) F
2 S( l0 J! k# W2 {: t( R2 f   CComPtr < IHTMLDocument2 > spDoc;
( h# P& g$ @  {: Z; p   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );6 z# y/ @1 ?- L4 S2 _. s7 n
  if ( FAILED ( hr ) )   return;
$ }. B, b. Z2 D* x
+ y0 l7 ?8 D/ V! v+ I) p( H   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针' _; _7 I: v. {) A
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 03:31 , Processed in 0.035407 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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