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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
, E! d6 B# i* _; c
7 H, _- ?, O( u  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
0 y! r( O0 V- O. l! S3 x& H0 }        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
! ^) `% N: E/ v8 h  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。3 L/ g, e0 {. o5 G' X3 M
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。, @) o8 }- L7 b% P, p- k+ m* C8 v) G
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。) |) R. q. s9 f. e1 \* ?
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
6 e, G$ v" d3 n( Z; E6 e8 m  P# c% ]6 ]! Z
CComPtr < IOleContainer > spContainer;
; B( C# v6 S& W. q7 Um_spClientSite->GetContainer( &spContainer );" w) ^9 k; W& Z
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;& b: }7 w% r$ X# v
if ( spDoc )# C) m! h  H+ C7 P# j1 D
{7 o4 S4 Y0 f; s: Y5 D0 G* N
    // 已经得到了 IHTMLDocument2 的接口指针8 ]  o; i, v! j1 e* g% O. P
}
4 h, T4 g7 y# g$ P  f7 G! U2 d/ o* L8 o/ a, h9 I
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。0 d, `: Y. L, b, W$ {9 q1 m
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。% t! v/ D# _. l: T" d  D
  <5> IE 浏览器作为独立的进程正在运行。" b/ R- u& B7 D; y% ]! `/ S# m8 x: p
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:' n; R8 R& l) C' F" g- e* N
/ H/ Z" y: C  T* |+ M$ Z- u
#include < atlbase.h >( H# k2 f8 Z& g, `8 f# C0 s
#include < mshtml.h >) Q! s  K9 N, o1 f

1 L4 l1 B# I, d6 A& f3 t1 r2 Fvoid FindFromShell()
( m' ]2 W* L, ?2 F7 Q. Y6 O% w{
, m: e: Y) J3 S, D* ?8 k   CComPtr< IShellWindows > spShellWin;
6 P! ?4 m# _  M/ E9 W   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
, I( Y# B" Y9 E$ s% C7 x2 B2 k5 x1 d   if ( FAILED( hr ) )    return;
# d: |5 |: H& m$ Q" m; C
* _; Y# [1 d/ S0 @1 X% e   long nCount=0;$ a+ u# h; P3 {" G: a3 I1 {% u
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
- B: A- {8 Y/ R8 j/ z$ f
$ y  }& W9 V0 ]8 K2 O! A" k$ N   for(long i=0; i<nCount; i++)# P6 t5 F* ~! b; F, N
      {
+ M! I; @$ n. {4 w                CComPtr< IDispatch > spDisp;
1 h  I  K5 J( D# d4 i6 `      hr=spShellWin->Item(CComVariant( i ), &spDisp );6 Y0 @- G% _3 }, @% x" s, T: L1 y
     if ( FAILED( hr ) )   continue;& s+ d5 G2 C6 e. ?5 W

0 P  K4 |0 o7 J: h" }      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;- v' R8 C7 u% I/ i  \( I) t
     if ( !spBrowser )     continue;
. X8 J6 @' s6 Y
+ e( U& C* `: J; u" o      spDisp.Release();
  X' Q3 I, H, T# O      hr = spBrowser->get_Document( &spDisp );
. R3 f8 [  N; b7 \! h9 q$ y      if ( FAILED ( hr ) )  continue;' t( @1 q+ O* F1 y4 m. c2 w: ]

; Q5 F7 U) \! x* z2 }# g      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;2 i( w0 S" k% [; R' ~, ?8 Y
     if ( !spDoc )         continue;
4 r: W3 O2 H; ]& V4 Y7 |1 ]5 M/ b8 V6 g& P) M
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
4 x$ x% F* _6 p- l5 J3 T   }
3 P7 s) Z! \4 `}; h3 n& B0 c  a2 v9 x" Z
2 o9 B7 m4 f5 P1 T0 o# o$ O# u$ ^
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: / U: K7 q4 H" Y# n; E3 D9 [
. |1 e7 u2 E* g/ E

( p$ C  |" G8 @6 [, W#include < atlbase.h >
; `. A' h# K# S+ A#include < mshtml.h >" r4 P, _- A) w+ w6 l
#include < oleacc.h ># T# A  E8 c. h- ^6 t
#pragma comment ( lib, "oleacc" )
9 u% K: @' Z8 ^  J( ]: r* `8 `! y
$ U# q0 k& [% fBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
- w; R, W% B& [, ]. l8 p{
9 Z& K/ A" A2 m2 E6 o& b   TCHAR szClassName[100];) K1 c# q, Q% G' I6 a9 f$ u" w

9 T* p4 r7 g9 S4 \$ T3 }4 P0 J; _, J   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );* A8 Y/ f+ e! V: x2 H
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
: B6 D8 }% M: ^1 f   {* B% m( D% h4 f$ X
     *(HWND*)lParam = hwnd;6 w2 K* R& S- H& d; D: w  v: E- t, }
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止, C. f' k% J# q, Z
  }
: w! a/ h' B* `* I   else   return TRUE;      // 继续枚举子窗口+ ?  x  K5 j5 A4 I/ ]
};
' \! \( u' B% m$ m# t& \) d' p& d7 N7 x
void FindFromHwnd(HWND hWnd)
& A* ^& M! R. T/ B2 u{
: k0 ?3 j1 c% _   HWND hWndChild=NULL;
! j& L( I7 \* ]. ~4 a   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );2 Z) }* t) y9 p9 w4 S
  if(NULL == hWndChild)   return;
8 A4 h2 _$ j  L3 m2 Z; V7 |+ Z  h7 ]. g/ I8 k5 S# n
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );3 D2 i. l: a- ?* q9 |  R2 ]# R
  LRESULT lRes;+ f) k* i( d3 A. V
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
, V' {. ~+ H" ]' f6 }0 \: g
2 p* N/ k+ \3 i# m( z8 j; y9 r   CComPtr < IHTMLDocument2 > spDoc;
9 W2 y1 L) z4 }. a& _; g   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );; X+ s) v: A$ t8 R0 x
  if ( FAILED ( hr ) )   return;
) W2 K( e* {2 r6 V3 i* I! D3 i$ z' ]% O5 ?/ g% ^" F1 C+ Q
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
; F! L( Q2 y: d1 _; ~, e5 b}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-15 06:17 , Processed in 0.017386 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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