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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
0 ?  K, T$ q9 N
. g5 p9 ^! \* t: q# s  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。* X0 a3 E9 K8 Z; ]
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
. s, O% z& n1 E- `2 X) h' k* r  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
, q. e. W* Q* J$ U        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
2 q( a9 E3 B" S! S1 H; ^; X# d  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。2 o0 ]  z3 r( S
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
0 a. O3 P% k4 O/ W: F4 i9 c( ?4 g- p' I
CComPtr < IOleContainer > spContainer;
) c+ \! w" W" H. Y- |* h7 bm_spClientSite->GetContainer( &spContainer );4 G- b8 J5 p* _6 ]3 k
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
1 _* M# j7 _1 V( \* W) S3 cif ( spDoc )
5 Q2 x0 A1 d) m, R7 r/ h! V& A{8 Q! H! v8 O* F. r7 a
    // 已经得到了 IHTMLDocument2 的接口指针2 ]7 C* V- {/ K' H
}
3 W$ T/ t0 X% }8 S$ F( ~6 @! x
: g# ^) @$ b* Q' h" E& M  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
, e( `0 D5 m% i* {) \) p5 t        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。! |5 y" A1 Y& U
  <5> IE 浏览器作为独立的进程正在运行。$ P" n1 p/ B$ u! y4 p2 n" E9 v
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
% A9 v4 R& B- o  L9 Y0 c4 Q; e. x9 u8 G, J+ D6 p8 F& `, U
#include < atlbase.h >
5 r! i* ^" R! z/ X' @#include < mshtml.h >5 `  _% [$ ?$ q1 e) A/ l
+ ~7 J- Y, q" k
void FindFromShell()
; P& g& h5 k8 ~! r0 ?2 @+ T4 |+ q{% L' b" o$ M7 e; l# h7 f) l" }
  CComPtr< IShellWindows > spShellWin;
0 M# M& q6 f) s' e   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );4 `6 F. k  \: ]" [: f( S
  if ( FAILED( hr ) )    return;$ k6 l) k, G7 Q0 g& ~
( K' ]9 U) z4 y) a
  long nCount=0;$ r9 j4 E) X- {' S
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数# Z6 Y  g% v# V+ x
- C4 d/ K( U3 W7 _3 O& [/ c
  for(long i=0; i<nCount; i++)* O  V. O' u, ]. ]! r
      {
) J* Q( `: E+ C3 B! s                CComPtr< IDispatch > spDisp;
" q4 ^/ Q. k8 c7 q      hr=spShellWin->Item(CComVariant( i ), &spDisp );
3 ^) l1 b8 k+ h: L      if ( FAILED( hr ) )   continue;
7 O4 ]# z. v' b
3 u6 N' J. y' L      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;: Z  `* J/ E$ [3 U
     if ( !spBrowser )     continue;$ f3 Q* u+ i. S3 x( E$ J4 \* }4 p

5 y& V9 H1 f+ q; j, M      spDisp.Release();
/ J+ Y8 z6 j) V1 t5 b      hr = spBrowser->get_Document( &spDisp );
/ H  d6 D/ w) q' a9 Q      if ( FAILED ( hr ) )  continue;' z+ j6 }1 d1 W; h" @2 X; s

' q" w. T0 D9 `# p2 t6 _$ T& t; o      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;/ x: u1 l! j) K7 J( [% W" `
     if ( !spDoc )         continue;+ ?' S$ G  S' o" q2 H$ V. C
$ t" n) O, D/ M& @0 Q& S
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
/ Y8 b% r' U* h, p; z   }
' O# ]2 q. r3 k+ M5 S/ h}
, @* D! J' f( f0 s* ^7 x3 c
3 a6 C3 k) m2 `1 K  M( s; t  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: ( z9 {5 m; ?1 c  X; P8 h! P
/ A; V5 ~2 E+ D% w
6 b% Q4 F8 t4 J7 C8 T* I; [
#include < atlbase.h >" l0 f0 D4 D  ]* R- k
#include < mshtml.h >
7 B( o5 y+ c6 D% j& J#include < oleacc.h >1 L* }1 ~0 @, G) Y% }+ z. O
#pragma comment ( lib, "oleacc" )
$ f1 j9 p8 x" ~! |+ A' T0 i. P8 C
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
8 J# S. h# u* V{
% y' C, G4 N) F( R+ m   TCHAR szClassName[100];
( U. N4 O/ J& i6 b4 [5 C9 M0 V1 |7 w; _) X+ O  E
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
1 o4 X) m7 W! K2 a- D! l' M# g0 q" r; I   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
1 m* D: I# }& G   {
! E6 ?7 d3 t8 }. _- K2 l% Q      *(HWND*)lParam = hwnd;
2 ?1 a9 w# r2 Z- ]: c6 U: [      return FALSE;      // 找到第一个 IE 控件的子窗口就停止
+ e% A  q9 t# k1 F, w8 Z1 Q7 v   }
# A  F+ C* O8 K3 x9 t; b2 d   else   return TRUE;      // 继续枚举子窗口  n: b& f- s; B' r
};: |0 p' a; n, k2 P! F
9 M3 }7 X. i  p+ B; F
void FindFromHwnd(HWND hWnd) 2 x6 [2 Z+ h* z/ Q( N1 V0 Z/ R
{
) o3 u) }6 `+ V# z5 f, K   HWND hWndChild=NULL;
7 J4 b  J! X' G% w9 P; y) ]0 x   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
. T4 p6 y9 {4 E2 S  \% V  ]8 l   if(NULL == hWndChild)   return;+ E9 v2 J& E! S+ s) }  T
( o7 n; C  Y6 K) q5 \/ O
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
9 n: J$ s4 a5 n3 c! h   LRESULT lRes;; \. {) Q2 V2 |
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );9 J2 W0 C5 L6 m
0 P' `4 h! S" }$ g: `
  CComPtr < IHTMLDocument2 > spDoc;
- g6 G( a0 O% `4 l* p+ I5 {8 ]9 c: O   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );6 j& b+ i" l6 I+ C" [
  if ( FAILED ( hr ) )   return;
; R) P+ Z" s/ Y( Z( G
; h- D0 c1 w: y2 I+ Y9 n   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针: d/ n! T9 [$ s
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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