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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。( m; u/ [2 I# l- u0 a

7 o# G+ y; Y: L; ~  f) X  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
6 |/ a  Q2 e5 O! U+ E4 `        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
; R  M" {- }% R7 ]/ q3 j) X  P  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
' ~! B& a: ^! a9 m' p; m" \        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。/ [+ S# R/ b  A) _  I
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
1 r1 }/ w8 Z0 _2 q0 M8 l2 ^        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
2 [; M" t% R9 g9 {
+ z' d' p# l$ \* bCComPtr < IOleContainer > spContainer;
' b/ O! \+ N1 K7 Pm_spClientSite->GetContainer( &spContainer );/ H9 Y* l9 r9 t$ ~9 Z
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
' T# q" M# m! [+ Pif ( spDoc )
0 p* h# v; @8 w8 ]{
0 H8 v9 Q# y6 |. R: A7 f     // 已经得到了 IHTMLDocument2 的接口指针
/ S6 J# u0 T1 N" S& _7 w}
% c5 l" I9 B9 D2 Y$ X# s2 P+ ^2 }/ a5 z
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。- m4 ^7 I; C9 m  d9 S
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。: x, u3 [4 ?. O! d+ N
  <5> IE 浏览器作为独立的进程正在运行。( M) a* H5 i9 F( I6 v' B
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:) h1 \" I0 f( \- ^

- q/ }1 x- a: }! L#include < atlbase.h >8 @/ I, J7 g( E& W/ F
#include < mshtml.h >
" W  o' z* y! C( R) {& ?' y" a8 R' t; k6 A
void FindFromShell() - L1 l( o* C  K- F4 {
{
! g, |  D2 s! W" L3 @" I. w' f   CComPtr< IShellWindows > spShellWin;7 J( X# U. b* z$ v7 X1 d9 f
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
& O$ S7 X# X, }# D% g   if ( FAILED( hr ) )    return;
0 E0 f/ G3 U$ E3 @
9 k5 C9 M# V+ d4 N, y   long nCount=0;
+ s8 u- e# D( O. _, G   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数$ M* D, y* o2 E: e

) G( w# _( K! u& g  P   for(long i=0; i<nCount; i++)
( Y) Y! P, _% v: E6 N       {
* W, Y" F# G3 n7 Q9 Y1 V  P                CComPtr< IDispatch > spDisp;7 j, M& ^7 C. ?- Z$ Q: t
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
/ \# E) s; P8 T" A9 S, R      if ( FAILED( hr ) )   continue;4 \4 D% ]7 \$ ]

7 z5 O) }& x9 z% v& v7 c) N      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;/ t' u2 ]) z) @' l5 X! H) n
     if ( !spBrowser )     continue;
, N; J, E) G3 x2 O% [1 ]! ^7 M+ K" [3 L% W4 T
     spDisp.Release();. M" j: c* v: s: J$ b/ d
     hr = spBrowser->get_Document( &spDisp );
& c- r5 @2 E0 j! Q: k) z, \7 R      if ( FAILED ( hr ) )  continue;' i: D/ [/ r) A7 {' O" E. ^
6 C: u- @" G8 R9 i3 z6 J
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
# U; {- N& w( n. E" q      if ( !spDoc )         continue;) s2 l# R4 q  `

( n' i8 h) m$ K; C  u' V' e      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
6 H0 X8 W4 w- T2 j, a% J   }
7 b+ M( T* ~% m9 G9 O/ f5 z}; R% o2 K7 K+ m7 P) D
$ L8 y1 u/ G3 @
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
( u1 E; A  S5 j& p2 W4 T
% K9 l( C" ?9 O  V2 D7 t/ K+ e( R( v7 i
#include < atlbase.h >& j- `- I- r; W  i
#include < mshtml.h >) d( e4 L- o, ^
#include < oleacc.h >
/ {: i' }+ C& V7 `( L0 |#pragma comment ( lib, "oleacc" )) {" ]  h3 ]$ ^5 P2 {, R- l

- _# g6 \) n( ^* O# e: KBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam); L: p! V- O# d0 J6 n* P' R/ s
{
- p0 Z$ O# g9 e+ v5 h   TCHAR szClassName[100];2 h0 t3 o8 z5 b. v+ E! x1 o; E' `- K

' r  [! `. k& W   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
9 G; `7 ?4 W1 C* y   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
2 o+ q' x4 h, V" t   {" m; Y: [2 D& v$ R& X0 p8 l
     *(HWND*)lParam = hwnd;
+ j; F( u; [6 V: l# y/ e& N      return FALSE;      // 找到第一个 IE 控件的子窗口就停止! s% P0 Q6 [) |" N+ Z, ~: N1 p
  }+ {" r; c$ E& [; ^) t
  else   return TRUE;      // 继续枚举子窗口
" M9 n5 s* B; {" b7 H. F# c( Z};
" |( z3 n/ p8 f7 F( I7 N* W
! f6 Z' N; s! _( f- ]void FindFromHwnd(HWND hWnd)
- o1 _0 S# ]& a- i2 B, e9 m+ y{
$ B1 @! D0 C1 N/ @8 H   HWND hWndChild=NULL;
: A, s9 Q4 [) o; L! _   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );
* {: p: P6 }/ U% S: g3 V   if(NULL == hWndChild)   return;
5 C9 b& i: w+ \8 a! x% W5 w8 `0 K# h/ E7 B
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );, d: i! N: Z2 h8 p4 g
  LRESULT lRes;6 E( ]: C) x. P( {& c9 g
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
( q1 t* ^5 |2 A/ r) [4 v# a+ m
4 C* {9 e% T! w7 I# q8 J   CComPtr < IHTMLDocument2 > spDoc;
4 d, m& v2 v* n% O/ Q0 s$ i. P   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );( v; J1 ?7 _) Q: u
  if ( FAILED ( hr ) )   return;* Y! z+ e. W4 z# R# \. m. V$ R
" `+ D, L& g! n( \8 z% T
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 m- W5 M+ O, D
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 11:45 , Processed in 0.017002 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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