找回密码
 注册
查看: 4844|回复: 0

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。& b% Z4 Y- |$ E% A- k7 T& N2 v2 Z$ F# U
3 h/ U. O3 @7 K. o
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
/ y# l' b2 R) {2 q5 B        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
& Z8 F, Q" F" U& G  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。; J. U) p; v9 i
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。' |: H/ U, W: `3 i2 e6 j7 G* _
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
' b9 S0 b- _! e% i        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
; R3 [7 G" ~6 L% Y  u1 c# e8 h
CComPtr < IOleContainer > spContainer;) {: r: m' `7 t* s" I: d: Q+ [  f
m_spClientSite->GetContainer( &spContainer );
0 Y1 p7 t* L, ?1 M) n/ T8 CCComQIPtr < IHTMLDocument2 > spDoc = spContainer;, |# `2 Q, v, g
if ( spDoc )9 X2 Y  J/ \8 q* S& C# z% q. y
{
/ {- c# D- j7 q/ u- u0 H9 Z     // 已经得到了 IHTMLDocument2 的接口指针
" Q( d2 `  ^, @4 p}" W/ J9 G- S+ S# t3 J- k" H

  F3 ~" n  j+ x  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。( B6 V1 T6 t6 Y* O. k
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& m; B0 ~) N0 l  <5> IE 浏览器作为独立的进程正在运行。
0 t) C: Z  B3 S        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:1 l7 ]% A* w! o1 w; D* d9 F
9 A8 g% ]4 K7 u% `( I
#include < atlbase.h >3 k: y/ }  I+ ~/ i. `0 K
#include < mshtml.h >( x" P  H9 }; [' Y4 X+ h- v
/ ~8 X4 D* t) r& ]) g; d
void FindFromShell() / B+ u( L& |) G  v0 g
{& X$ y8 d8 c1 x% P
  CComPtr< IShellWindows > spShellWin;
, U7 G; [9 I' S& p( P9 z* Y7 k   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
3 S2 D9 M7 ?+ y" \9 r+ @2 j/ i   if ( FAILED( hr ) )    return;
0 O0 ^: f4 H4 a. u4 q' _
3 F: l( q. l6 I# R   long nCount=0;, m+ r% \- K& S
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数+ h. L: u+ {* {8 M7 g) O. S

) |1 a2 a6 \" b* t   for(long i=0; i<nCount; i++)- m* W* b) r5 W: U: Z
      {) B; }( l6 t  n
               CComPtr< IDispatch > spDisp;
. m. Q* ]4 }$ y1 F. @      hr=spShellWin->Item(CComVariant( i ), &spDisp );
0 L% g) L" r5 b" ?      if ( FAILED( hr ) )   continue;
1 S" C% i( ]. ?6 O; k3 M* [; i0 U' J$ f) t
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;8 ]! J0 S5 a' m+ b7 y0 @
     if ( !spBrowser )     continue;
9 g% {2 U9 z5 Q# r' s4 d/ r1 c2 o
' U+ U  R0 f' Y4 ^& ]      spDisp.Release();
2 q5 O$ R6 G7 o( a5 X      hr = spBrowser->get_Document( &spDisp );/ g4 Y1 d; Y) D% p& D" L2 G; o
     if ( FAILED ( hr ) )  continue;
+ G# c5 ^. C$ Z% @" T9 @  h5 L( ^: O) Z- e# T7 e
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
: ?% R) Q$ v+ x; J6 ?7 H$ x      if ( !spDoc )         continue;  K! j4 i! E) T7 ?5 P5 \6 ^

( l1 z- M& m( U8 k% {7 f) _      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
! ]. Q; e1 N7 X5 r   }3 ^, h* P, c; b
}5 w7 z+ z, P2 O& J/ P* Q
: R* Y7 l: }! m  \
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
- y9 S$ W9 H( S# z
! i  f4 V+ c$ x: ^
& k- O4 Y2 k' v#include < atlbase.h >8 H7 F9 I" Q1 m9 h
#include < mshtml.h >
$ E$ J& n; e( i* z$ y; ^" O2 K#include < oleacc.h >$ Y, ?; Q) q) l% ~7 E4 N3 J
#pragma comment ( lib, "oleacc" )- v2 @7 I9 F/ J+ ?; f
3 M' e" m5 l4 Z5 f
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)' Y4 v/ w# ]( S: I) S
{( R! m! z6 E6 \# A2 v6 J9 _
  TCHAR szClassName[100];
8 e' ~0 z. I$ y( h% A) i% `# R3 u
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
3 Y- ?6 s% J, ]# R5 c   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )+ V1 B. ]6 _6 M' N- M. o6 V9 l
  {0 P# l' M2 _8 n) y2 _  j
     *(HWND*)lParam = hwnd;* {5 @; o# t  G4 g' _1 o5 R! S
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止5 p" H, {* [# ?% w1 j% {* [
  }5 k; J! o8 H+ N
  else   return TRUE;      // 继续枚举子窗口; X" X, l" G( n0 l# b
};! P9 {  ^) K) ?7 s; {2 q7 O

. t: L5 V& ?2 r! ~void FindFromHwnd(HWND hWnd)
5 C! ^7 U) r0 f9 e+ k& Q  f{
4 W) R; Y4 T6 S' F6 g   HWND hWndChild=NULL;6 _6 J3 `9 F* u0 ~8 t: Q* Q8 X8 H/ S
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );! h" `" ?" L7 c* c
  if(NULL == hWndChild)   return;
3 {/ j$ l/ ?- ^! d' W  w' D: f2 x# Y& l% I' [! U# M; P* @
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
! v6 W* G7 f/ N+ ^1 F   LRESULT lRes;' z, m& _: I( E
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
6 \. T0 k# G1 Q3 Y2 X5 g6 R* w9 A; ?7 M& Z6 V: z
  CComPtr < IHTMLDocument2 > spDoc;2 T; [( E. @9 g' g# P
  HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );0 e( n0 V0 G& h* B7 ]% s
  if ( FAILED ( hr ) )   return;6 C# {" J3 v7 _! G& n
. H% x3 V' r- _  d* z) J3 ^
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针8 l" f4 I7 W. o) ?
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 20:47 , Processed in 0.018877 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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