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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。
' W4 B/ e; K5 N* T1 Q/ q0 c0 c# g2 f. F: |" i
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。. G! d5 a9 u( i5 H0 o4 t
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。' [, d- L& \8 ~( l$ v  z) j
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。' t/ ~/ E; Y6 r
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
6 T3 M+ d0 j# n  H4 I  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
4 l2 O: t0 J7 R( |/ E3 G        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: ( q9 P9 H/ ]4 n

1 w! J8 @) I" O1 K6 |CComPtr < IOleContainer > spContainer;1 F; Q5 C( k$ j# t) B6 a
m_spClientSite->GetContainer( &spContainer );
3 F& s4 z! n2 b" M) G$ pCComQIPtr < IHTMLDocument2 > spDoc = spContainer;8 @4 p/ A$ g/ V; G8 X
if ( spDoc )
' M' s9 n  Z7 ?$ ?; T2 _( i{
# H: a( a9 W: j* z" J& @     // 已经得到了 IHTMLDocument2 的接口指针
, [: c/ G' ?. E# L' \. T}
' M. A. I& D: K# A
) f1 {% d+ |' Q  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。8 P+ ~; p/ [6 [4 Y5 r
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& a+ n$ K6 V# N) S) g. Y6 Q  <5> IE 浏览器作为独立的进程正在运行。
2 F7 {; u3 x7 S. \        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
. \4 T2 ]$ Q1 v3 I% [# m9 ^+ C% K" g: |) \( H& l
#include < atlbase.h >
( C) ]4 q% @; E#include < mshtml.h >( d( a) X; G& k* z

1 U! t! r  ?) Gvoid FindFromShell()
4 e, p2 ^' k- @. T5 i; w{+ A. J, U8 e6 |# u' h- W
  CComPtr< IShellWindows > spShellWin;1 Q! y# M# U+ S/ z8 w
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
- S7 k5 p: L+ U$ L) b9 V. S1 Q  n   if ( FAILED( hr ) )    return;
! A, w( x' x6 |3 R2 r4 E5 A3 I; y$ ?1 H# _- ]
  long nCount=0;+ A% a/ L' _& B1 A# c
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数! m; G& @" [, |$ J$ T5 a

& r3 P2 }5 a* Z- @; L: x% s8 F5 I; f   for(long i=0; i<nCount; i++)5 N: G, V7 C! o* s3 W% L2 D/ ?
      {
, j! I  ~. {1 b; z8 |4 \- R& T+ W+ e                CComPtr< IDispatch > spDisp;* h- G( E; m7 Y: l
     hr=spShellWin->Item(CComVariant( i ), &spDisp );+ H; M$ i6 K8 ]4 D6 I, l% e
     if ( FAILED( hr ) )   continue;, i8 p) A. a7 v9 X  Z3 M% G

' R/ A7 o% }) t  S1 Y      CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
9 G& f/ u. `% o* s      if ( !spBrowser )     continue;. ^% S& e3 e  y! P0 M7 i

& Z% N0 t, ~& N% O      spDisp.Release();
; P- C! a; Q$ h+ c8 T" ?      hr = spBrowser->get_Document( &spDisp );
3 q1 R/ J% i6 W# k1 R* n# _# |$ Q9 k      if ( FAILED ( hr ) )  continue;; P% ?7 h% t7 d6 {
  t  ?# B7 P; ^& U
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;4 `  g+ H& X$ ?( E) A
     if ( !spDoc )         continue;7 x- T5 W5 Y( m) C
3 c. W7 n" ?- ?7 B. L6 L6 m
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针8 h/ u; Q3 z: e- T. p9 d
  }
+ X, @0 W' }: l% W& Y}! K, M3 j) b+ g0 L% a- B
" m' i1 a, o4 N7 N! _+ e/ c, r
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: . r7 C9 P4 f9 M! k' p

7 o- }. i: f$ T. B5 G1 _
2 B1 t4 g2 A/ z+ W8 ^6 P* B3 C' u#include < atlbase.h >5 O1 j- h) H& S# }
#include < mshtml.h >  f( X3 ^) p  n7 f( \
#include < oleacc.h >
. x' z9 g9 J" {0 m#pragma comment ( lib, "oleacc" )8 W6 J+ x7 g/ }  h$ F/ ~5 Q

4 w& ^/ G+ s; T$ T! ]: ]# U/ N$ qBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)& h+ n' `# e% f, F$ |/ ]: r0 O
{
$ q6 ^8 ^! M3 l) ?, o9 \, M   TCHAR szClassName[100];" }; N& R2 a1 D" P- M8 P! r

' y1 Q% O) K9 c( ]5 \   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
; G2 N6 U; c) M7 L' j3 H6 |. @   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )$ }2 N9 p7 S, b9 m( n7 J0 o7 l, u3 r
  {
& U- ~- i2 }8 q& a      *(HWND*)lParam = hwnd;
8 Z4 k* r3 n) r2 {2 y7 c# q      return FALSE;      // 找到第一个 IE 控件的子窗口就停止; p- x4 c2 H) g$ y$ k, Q8 J# s
  }
4 b9 i+ G2 a5 q4 p2 K3 @   else   return TRUE;      // 继续枚举子窗口- r+ p" [" t3 {9 x/ J8 Q
};8 I0 D: V* E9 P$ s! p7 P
6 I* J  L. B  h
void FindFromHwnd(HWND hWnd) 9 M$ f) e& t/ ?0 }- }( e& e
{
  h/ K% B+ |5 y/ p   HWND hWndChild=NULL;$ W9 o$ I' r" A% y  S' D
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );, S5 n/ Q7 g- i2 u* a
  if(NULL == hWndChild)   return;4 @9 H0 |8 B3 {. f
- w* a8 F( x% W# V/ R5 g
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );- K) r6 c1 k4 x2 R; a5 A
  LRESULT lRes;
+ t% G1 X4 \8 u- x   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );  F3 z9 Q8 u$ d1 l
/ S8 C6 y- a6 I! O; W8 z
  CComPtr < IHTMLDocument2 > spDoc;
8 e% E$ J2 T% a) w  i+ f; @   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
* ~3 |# p7 N+ G# N* U" Z   if ( FAILED ( hr ) )   return;3 e! e4 I% y- `4 J+ {" }/ `
5 [( N3 x1 b% ?# T& \- h2 x
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针" {; ]7 H' r$ \4 T! _" v$ k& {: a
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-13 22:40 , Processed in 0.018628 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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