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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。  E: B$ U. k( I6 j. Z: p4 `
, X. {: K! Q9 R! X' ^9 I$ l' w
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。5 ~0 O' L, e" U
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
5 x- X& t, f6 n, k$ D  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。4 \# h0 c3 [4 @' q" G
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。$ [; b6 z; H. m: Y
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
* L6 Q4 j" `( k5 f" E4 E  J        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
! N" l4 ^0 _& Y
! k+ v! s! H. Z& ]" ZCComPtr < IOleContainer > spContainer;9 I% D4 S1 i' h& U. z1 ]2 R4 P
m_spClientSite->GetContainer( &spContainer );/ ~: v  `  A% Y2 T( a' R  \5 j8 l/ w  \
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;
% h+ Y' u7 X% l9 C% `+ A( x  tif ( spDoc )
" Q8 y( @' S  {$ m{2 Y$ i" _; d  O" K8 E. `
    // 已经得到了 IHTMLDocument2 的接口指针
$ \2 s4 u: [8 e. t4 z# S0 A}/ @, S- H6 A1 q2 N2 r# x6 m
+ v4 ]2 T$ ]. ~6 B" ]$ p4 W  r
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
7 k  A/ A, K/ r8 V2 U7 E: \        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
- Y) o* Q! C' b2 f  <5> IE 浏览器作为独立的进程正在运行。
2 O; ?& H' e/ W, P        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
3 ^7 _- o0 E9 _& F1 o0 r$ W! o' E$ D+ x: Q) ]5 I+ T  E$ W
#include < atlbase.h >
; b; R5 g  c: v3 S2 X* {, J! o#include < mshtml.h >& {- f; x8 Z: r2 y! ~" d. \3 j
# `$ K9 f8 n+ B( v. M! l: J
void FindFromShell()
5 W  s/ n7 s9 N/ M  a{
) l, @+ q, N8 d' `' d   CComPtr< IShellWindows > spShellWin;
* z! L1 Z0 a& n& w4 t2 r* w   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
% Y, |5 T( c1 I   if ( FAILED( hr ) )    return;
6 N6 e, R- ^$ k+ n% L
8 n% |' E, z9 M* P7 v   long nCount=0;
- r5 t5 r7 b& p4 ]' X   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
" K/ D% h" d- s3 `- Y# {6 H6 u7 a4 \7 g7 e7 T. P" ~0 @& p
  for(long i=0; i<nCount; i++)2 K7 G$ D/ G2 S4 V
      {
( s5 \3 e2 u$ D8 w% N                CComPtr< IDispatch > spDisp;
3 {% b0 j4 ^; z$ y      hr=spShellWin->Item(CComVariant( i ), &spDisp );7 o9 I6 s( x- g, Q) ^4 l
     if ( FAILED( hr ) )   continue;# |" ]  U: B* p( a
% E. W7 D/ j- j( n8 |: s
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
# U% p; v1 W7 r( ?      if ( !spBrowser )     continue;. K& X% U. x/ ?5 h! J# p

& u7 D) ~! i0 W! L" k      spDisp.Release();3 {0 c; M6 M. F
     hr = spBrowser->get_Document( &spDisp );
  V$ R( T8 u/ l# H      if ( FAILED ( hr ) )  continue;# p1 c2 E+ j+ h  B( L- Y6 y
% Y! @8 [* X& C
     CComQIPtr< IHTMLDocument2 > spDoc = spDisp;
' k3 ]9 e% f; Y* u* O2 r      if ( !spDoc )         continue;
. V, ], B; G$ x( k$ B* Q9 I
8 \; \0 j! ^1 L: L% Y' n      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针, q" v) K8 z* V4 D
  }3 ^$ s8 ~# h7 b( z8 h
}
3 ^: w7 t: n1 z
* q7 Q; j" p5 T. M$ f7 A- L: I  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
1 P7 g0 O& @+ \4 `( w6 D4 Z
) k8 `  }- {6 ]$ t9 X
% a4 u5 j$ T6 }4 A8 D/ X6 P#include < atlbase.h >
5 O3 x/ g( Q& m3 x+ O: I( I#include < mshtml.h >
7 v) q9 S& L+ q/ e+ ~7 Q#include < oleacc.h >
1 |# M7 h$ y2 l4 C#pragma comment ( lib, "oleacc" )$ @3 R2 ~1 b* {/ D: ]' Y

$ c# n6 O; g* f- k) OBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
. O2 f; E3 U, C  R9 N( @. t{
; N% p+ Q9 q9 ?6 H   TCHAR szClassName[100];" P5 p5 k. S" e5 a8 {: Q; V# k/ q

4 |3 j4 a1 v/ e8 W8 _, I6 d   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );% w; U0 ~" a1 V
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
+ t' a2 `& \; l2 A# K, R" h   {
; J1 b' [$ f4 ?, \. K! r      *(HWND*)lParam = hwnd;' M& h- \2 y. k. n! d* r
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止0 B& N) e4 R! u% y( o
  }1 J7 ^) {' y* L/ O) K; @; |9 x
  else   return TRUE;      // 继续枚举子窗口8 O  T9 G. t6 H' @) U6 [: X0 d4 H
};+ G& T1 U7 `6 I, K7 }
1 S& Y( Y8 t4 o, h; ~% z5 U6 [
void FindFromHwnd(HWND hWnd) ( \! H$ l0 U9 b
{
6 ?. z1 O' T' G% K   HWND hWndChild=NULL;
( j, s  f$ L9 c' j   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );5 J; a0 O' V- G
  if(NULL == hWndChild)   return;
- v2 V! Y2 s% l# M5 ^) G
! A$ {4 J, o% P: k4 S* m3 H   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );) J. u! N2 h+ R) c
  LRESULT lRes;
# W5 j4 Z0 O3 U   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );: U# y/ U4 Y; F' q8 g) n4 @

" I9 z: t# Z, ]1 ?- x6 T; S( o   CComPtr < IHTMLDocument2 > spDoc;
' a5 x1 ?0 ~/ N! ]" J* {; K0 {   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
  a2 g- t) o' Q3 F# q8 P. C   if ( FAILED ( hr ) )   return;+ r* W3 k3 g. j5 c* F1 K! F+ T
( K: V3 Q) W) F! J& ]$ a
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
0 X; V$ S, @. f, }1 m! d}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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