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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。9 N( ~) d/ n+ `/ J
: g; K! H1 M5 [+ q" _8 v' K
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。% {& s# T0 P* W: w/ l
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。' l$ b  {7 P$ r  b1 X$ T' a% @- D
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
. Y0 M5 t7 j# b% [        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
3 |0 J. m- D, `" L) y9 G  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
) b5 I" B1 N# ^/ @$ t0 J: ^        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
8 J4 L( z" P- p% d
, y) S1 E/ B. \2 j/ r, R4 j! R* nCComPtr < IOleContainer > spContainer;
# \5 U2 x  Z0 t1 m& Fm_spClientSite->GetContainer( &spContainer );: {7 O( z' V/ c; _7 X
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;/ j/ c5 s; U* F8 N
if ( spDoc )* {" j- A" D0 S! a
{
2 v( M, {9 I3 f  y$ S/ H; A$ {( \5 \     // 已经得到了 IHTMLDocument2 的接口指针* u5 Y- u& j0 ~
}$ C# e: A1 N3 x) @' Y6 b; ?
/ s7 C" \* Z6 f
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。3 N- u8 p( Y3 o) m/ [; R
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。; \. s* y3 ~9 R4 {0 Y( g$ r
  <5> IE 浏览器作为独立的进程正在运行。
! y, L, D+ C6 J- B: P        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:  o% h. w, ^2 e) V  Y' a8 X4 V

! n( w" `: H* s6 R#include < atlbase.h >
4 m: S( v$ B# g9 }) x#include < mshtml.h >
3 n& p+ i' v7 o' [6 q' t5 d+ o
# G$ V7 \; V. [void FindFromShell()
9 }3 {  q, f* h  g{7 z$ i0 _) F0 J
  CComPtr< IShellWindows > spShellWin;
" |$ ?( t4 M  r. c( l) K   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
& _# @: j$ m4 I) a. U   if ( FAILED( hr ) )    return;
4 v  ?% i6 Q; t- {0 A/ A0 t. w
+ a# I( f# a0 b0 {   long nCount=0;
  q8 M% s6 r5 N2 p5 [' f0 ]0 O   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
& ?1 c9 Y' N+ j# r4 x* t% j4 L. g: e5 g4 A" w3 D* E
  for(long i=0; i<nCount; i++)
3 D+ m8 S% k! ~/ C       {
. Q) V3 Y/ H9 ~0 A6 S8 D                CComPtr< IDispatch > spDisp;
8 E! X& _. W' V1 ^$ h" P& d      hr=spShellWin->Item(CComVariant( i ), &spDisp );
, X. P0 ~  b' R      if ( FAILED( hr ) )   continue;
* t: D: d  q4 c' c/ A( |. }) Z* y1 |5 S% ~
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;1 _% M. U2 U  Y# V& [
     if ( !spBrowser )     continue;8 t% j* v& ?1 Z/ ~( v

  f9 D4 y. M5 K$ `3 z      spDisp.Release();
' ]; Y4 m! t* \+ Z      hr = spBrowser->get_Document( &spDisp );
) B5 j7 I! v1 p* w2 p# }7 X# a      if ( FAILED ( hr ) )  continue;( O# g" s% o0 R9 B& K1 Y

# _8 y; Y9 d1 H& q0 D/ S3 \, P      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;4 a) Q7 ^9 l6 w/ q0 U; g/ Y3 t" `  w
     if ( !spDoc )         continue;
9 j0 X6 U9 t8 x) j. C
. J( C9 n) h& O5 M      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
1 g3 e8 r' X' D; ~$ @   }9 D: Q" I- v' w+ n% @# i
}- k4 {! Q. B  T7 H$ p% I

% o5 ^4 i/ H9 |1 u  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: , U. H% \0 w$ r" O
/ |9 w; I0 x* l

! S( \: O7 t/ G5 S#include < atlbase.h >
0 [: |! S. T( [( b#include < mshtml.h >
3 @6 X3 s2 c- }. m; }#include < oleacc.h >+ t1 E8 G  O4 i2 k( T7 U
#pragma comment ( lib, "oleacc" )
( d- W- p" M4 x0 @5 L2 h4 ^5 v1 u6 O- M% X, a# `6 ?! d) a
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)! S' Y4 g' ~; s7 d* Y- z8 t8 _
{. |+ R, t# o+ b2 W
  TCHAR szClassName[100];) x/ j; c% I" E

5 z# Y* G2 P. G) N6 T' p9 G/ p   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );  q; m9 a, Q4 Z
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )$ b/ y0 F' [" m( [) {
  {
( X' _* {+ k8 S! ?  K      *(HWND*)lParam = hwnd;
- ~5 u7 l# l- G& Z. _( u' I: s, H      return FALSE;      // 找到第一个 IE 控件的子窗口就停止
& K* t2 w, K5 _9 ~: |   }  V' T7 Z/ }$ C, i. y/ f
  else   return TRUE;      // 继续枚举子窗口; k( U2 I* s2 Y7 i
};3 E3 N/ X! l8 |2 H
! R3 }; ?' t  z" A! J
void FindFromHwnd(HWND hWnd)
! {9 o1 K3 w( S- b# V0 W{: x6 j1 G2 y7 `. b
  HWND hWndChild=NULL;: a2 J) U+ z7 M- s- D
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );1 ^9 T$ Z5 s: K
  if(NULL == hWndChild)   return;  I" T% g' l( ?0 }4 x+ K3 Q
6 K! o) ~" ~# z( b2 [
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
8 D! v+ r9 X  \   LRESULT lRes;& V$ n/ e, J0 Y
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );# b4 i  r7 @/ v$ U* l+ h* u
& e: A  r( i: D" U
  CComPtr < IHTMLDocument2 > spDoc;. x+ V+ o. Y6 ]
  HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );0 Z$ a6 j1 N2 f# a+ E( M
  if ( FAILED ( hr ) )   return;! o# L) Y) y# L0 a. Z4 u
4 v- e& a# Y! j2 U
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针$ I3 Q' p& S  U% j% {
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-29 20:00 , Processed in 0.018217 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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