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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。2 C0 E$ D, i/ L% X9 T9 k
4 }/ m. B/ W) J8 l" B! G! z$ U
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。$ ?! b+ K7 C+ E1 w+ Z% D
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
% A$ ]+ b9 G4 H0 z  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。. _5 B- }( D3 ^2 M4 d5 U
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
' l5 a  w- C$ d  c: b' B  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。& G- [9 g4 H1 k, {! K6 R! \$ s9 c
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
$ t4 E0 e5 K( H* C) h; ~3 R
+ z# x) g' I0 e2 y+ E! uCComPtr < IOleContainer > spContainer;
- @8 C, K2 z5 e# d* N; Qm_spClientSite->GetContainer( &spContainer );
0 ~, o6 g2 Y; O- @0 u9 H! G3 U) qCComQIPtr < IHTMLDocument2 > spDoc = spContainer;
- q' z% S) u- D* eif ( spDoc )
7 X- v2 e9 I- l: g4 Z{
3 I. z6 H$ b# p/ k  E     // 已经得到了 IHTMLDocument2 的接口指针1 w% R3 c8 }. q' s: m+ J. d+ x3 o5 P
}- J6 a6 [0 n) i9 h  R8 w
% g% J! [- u1 f: K0 ~
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
# r6 w! h6 J% K        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
& }9 o/ w1 q  a/ T  <5> IE 浏览器作为独立的进程正在运行。
& ~  {7 }# s' {# i. a        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
2 Y) i- Z( x9 o# Q) U$ D* I9 J& b. r& l! ?
#include < atlbase.h >- D+ K/ H# h4 M. s
#include < mshtml.h >; E3 ^! w/ q3 D$ b# G* |' c
) |& a5 M8 V( m2 k, _; s/ g
void FindFromShell()
! v7 P/ z* k# ?  E- A{
" h- C6 u8 H3 M  M6 d$ g8 Q. y8 J- N   CComPtr< IShellWindows > spShellWin;
( n9 I  @" v7 i! B* z. X   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );/ d! G& z5 k2 V1 n+ X6 r
  if ( FAILED( hr ) )    return;% _9 \7 }: W0 s; x+ G) ^5 k
0 H$ q; }* m$ ~" B
  long nCount=0;
2 l4 E4 Q0 k  B+ ~' `  h, K4 z   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数- k: `: B9 z9 L- ~' X% r" [
- h5 G+ Y7 W1 g3 b2 w4 K4 @
  for(long i=0; i<nCount; i++). u/ |. }1 _* V! g. |5 s. y
      {
! ]* @; Q; q( o6 t                CComPtr< IDispatch > spDisp;1 L" Q) w" E% @% K* {+ Y
     hr=spShellWin->Item(CComVariant( i ), &spDisp );+ }) |+ s  v/ C; h, f# f7 ~9 D  A
     if ( FAILED( hr ) )   continue;
" N0 b$ D- r9 ^6 t) b: ]. O+ t+ a5 S) [7 L% x3 k' F8 P+ N! n
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
& ]# L$ ?; M, f) j2 E6 \/ P- I      if ( !spBrowser )     continue;
5 S7 X: T. h$ b
5 `6 k+ D( n' H8 A# Y      spDisp.Release();% _1 r) Q3 j" Z3 G% R
     hr = spBrowser->get_Document( &spDisp );
0 I* Y3 ^: C! {      if ( FAILED ( hr ) )  continue;
' }" b% d0 X, r/ F( t: U2 E
& T7 r5 e" q  G8 n% ]2 f: M4 z      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;8 N& y. z" g& B2 s3 N
     if ( !spDoc )         continue;
& c% R5 Q# m8 I- ~8 N( E2 B0 D- h  m
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针" q2 L7 ~* d0 v2 o- _- l: E; U
  }5 `* n& U9 P/ }4 b: P, d
}, p6 o7 e* p4 M4 Z. S) m& W
. W3 B) r) d" J, J
  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 1 g# U) b/ K+ y, f* ?& s
4 I1 Q$ Y( g( j, `) Q  `
/ X$ E. `. W$ ~* k/ |0 u3 @
#include < atlbase.h >" \8 B7 D" D& b1 v; C! d' y2 W# o8 g
#include < mshtml.h >
1 h6 y# x4 p+ n) W& ^' k+ f1 m  b#include < oleacc.h >
, ~7 a4 d& c0 Y: o. a, R; I/ C3 k. l#pragma comment ( lib, "oleacc" )& k6 [8 p/ {" d) g

- H# L2 J: b* ]2 y! A& f( `. m8 z* FBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
: |1 E' _0 i3 ?- a* c2 c0 ?4 a9 L. h{
  i; [$ P7 k; }. w( }   TCHAR szClassName[100];7 O9 \) N2 ?+ }) N3 z
# D: J. {2 X3 K: M5 E, t
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );2 M1 P, L/ u* k: Z
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
: z0 n4 S% h" E  l2 F   {9 p7 j' M: `9 D3 l6 j
     *(HWND*)lParam = hwnd;
* ~0 w, k: d% T% W      return FALSE;      // 找到第一个 IE 控件的子窗口就停止) I; \8 ^9 B& L2 u
  }
( y; _  r% N4 o- Z& d& U; u7 }" F3 G( Z   else   return TRUE;      // 继续枚举子窗口
5 B) [- ~7 R% g/ t- I, ^};* ^4 {2 w6 G6 i

/ Q% H, ^' [. f; J0 v3 B2 Y! hvoid FindFromHwnd(HWND hWnd) & a3 r( h0 _" v+ D: _8 u
{6 c8 q% {! F9 B) V9 N( D6 [# e
  HWND hWndChild=NULL;
) y9 o3 r7 ?" c. o0 ~+ q   ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );6 h/ G" `! n4 V; h+ B
  if(NULL == hWndChild)   return;0 v7 F  D0 @- R" ?5 `
4 @+ C+ T& k- E, ?7 D( S) X
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );$ K/ n, Y7 Y) o) {
  LRESULT lRes;' ^" _* R7 q" B. U: Z0 t
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );9 O/ O* s! p' g6 k* Q4 O: I

! X% z$ K& R1 F+ R   CComPtr < IHTMLDocument2 > spDoc;; q1 s8 c& c" r/ \: [
  HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
$ k% e2 [6 b# F1 x# {, p; A- \2 i$ q   if ( FAILED ( hr ) )   return;
- G1 c, c4 a/ }5 v  m+ s1 Q: X* ^: R; @5 D* I9 U& m0 N4 |
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针9 i/ [& |. Q" S( ?# w2 b1 m
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-5 04:59 , Processed in 0.014553 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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