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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。; f* h2 N! q: |3 V7 j$ g* U+ Q' A

7 A1 f, A+ ^/ I  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
/ X$ g( [! s; @# e8 }        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。0 \1 \' f, t0 s7 F3 q2 z
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。
/ l1 x8 j6 y3 f& x" o; P        取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。
  R8 H# q) a% U% M. w& w4 n( u8 M  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。( J" e# M6 [+ g" W
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下: 5 h' N2 L/ I8 V: ^

& I8 z$ s2 X# F0 T6 ^  q5 v3 RCComPtr < IOleContainer > spContainer;
' S4 a2 H9 ~2 q" r$ b: qm_spClientSite->GetContainer( &spContainer );
- n% t/ f( x+ x2 g& K, l' W+ C3 {CComQIPtr < IHTMLDocument2 > spDoc = spContainer;! f% Y/ i, X, F9 T
if ( spDoc ). l. R0 o$ {# c& i+ O/ ?
{
' d9 I* D& n6 w     // 已经得到了 IHTMLDocument2 的接口指针
# J8 W) [# S3 v1 q, A}
- i, u$ E( b, M, c
( l0 h  x7 E2 t/ ?& U, l. `  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。% p0 }. E8 _6 z# p( O* o: `
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
: g" @; u! c( p: X0 {  <5> IE 浏览器作为独立的进程正在运行。5 q2 p% K& P2 P7 `& z# k, M
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:; S$ t, y% C7 S  r6 @

: X& ^9 ~9 h+ F% z1 M) E& q#include < atlbase.h >
% m7 s" ?! P6 e( U/ l/ `8 k#include < mshtml.h >5 O/ s& ]- r4 ]' N

  [9 f6 e/ b( l$ A3 k- ]void FindFromShell() . \# Y0 q8 d, x; l
{4 ~/ m  h1 _' M3 P- B6 O0 P. @5 H
  CComPtr< IShellWindows > spShellWin;0 N; P# ]7 q' [
  HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );" w) E# g2 k& }
  if ( FAILED( hr ) )    return;8 v1 b6 ^/ H1 c' X) d

" {, E1 ^1 B+ H. e" R/ y  {   long nCount=0;8 }; a0 {* e" |8 g
  spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
% ]/ I- ~2 q3 j, k# l* o2 y6 z& f9 D
  for(long i=0; i<nCount; i++)
) ~% o. W- V- `" X       {# q4 D( \, X: W  q( @# y5 ?' _
               CComPtr< IDispatch > spDisp;8 f, Z1 i  ^2 a: W+ N9 e$ d" R0 }
     hr=spShellWin->Item(CComVariant( i ), &spDisp );/ q+ v# x' W$ T. i  N# w8 b) `: b
     if ( FAILED( hr ) )   continue;. A0 v/ o- }" A6 H7 o8 y
/ ]' t* ^$ {! [2 Y# D8 w
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;* }9 `: y' j- D- U2 q! H+ D
     if ( !spBrowser )     continue;8 u% e( }" u$ B, V) E! g" e) z

" `6 j/ D4 x% ]0 [" M' y      spDisp.Release();+ v/ V1 d- h! W% I) ]* h9 x
     hr = spBrowser->get_Document( &spDisp );
' }4 _2 J+ Z6 q, A      if ( FAILED ( hr ) )  continue;
% b8 _/ C+ Y  S# t* C
$ a1 V0 [- ]* M! A, e      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;) F3 B8 e( M" m9 b( K
     if ( !spDoc )         continue;
* j* k0 ?7 s& ^, A, N9 l: F( Z" ~8 P3 D! Y
     // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
2 y4 X0 R) b& S4 \7 e2 D   }: H$ Z4 Q9 _8 c% P9 k0 g
}3 S* C' z$ c- ~2 c+ }( ?

  K; e. p/ s4 }2 e, e9 X3 f' y  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
2 _; \* `6 n8 V) p, j0 X6 }6 ?( U
( z5 o' b* p- f; q& ?0 W# q$ O2 s2 L, R# Q2 w$ l! A
#include < atlbase.h >7 J0 C* r0 E% Q& A5 ]
#include < mshtml.h >
2 c& `5 h# I( I5 a- A# a& i/ K#include < oleacc.h >4 I' K( P3 ]5 l2 Y1 B
#pragma comment ( lib, "oleacc" )# ^) }+ g) f6 N3 [
, a2 Z2 e  @9 a! {  l" a. a
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam): Z; @/ L1 z2 v2 |) b! s
{
  m- K/ ~2 H" o; [+ O7 L   TCHAR szClassName[100];1 Z3 p. F7 `2 ?4 Z' {
/ O3 _2 q6 K' T  U9 |3 l) f7 Z
  ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
( V; f& s# A; _9 E* G   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )* u1 j# w  B  t/ n
  {
( [0 G9 H6 e8 N! a7 x9 [      *(HWND*)lParam = hwnd;+ A% l6 V4 }8 V! f) b9 H
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止: }- [3 f3 @+ l) j4 u& Z) u
  }1 n) J4 L& _6 f3 U* J2 T, ]
  else   return TRUE;      // 继续枚举子窗口
' W: z6 S- |% U1 ]* J};3 z- l  w) w) u: P1 b

5 a; z9 Q# [  Dvoid FindFromHwnd(HWND hWnd)
$ b  j( D& x, B9 O$ d{3 i7 N3 R* Y! U6 S0 g. O/ P
  HWND hWndChild=NULL;+ ]; ^6 c9 B8 c/ ^9 J8 `, N
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );/ S# ?4 F2 M0 l/ m: G3 y, u
  if(NULL == hWndChild)   return;: C! I; p2 l( x1 L! B% B
6 t2 \4 L9 S% b3 q, G* o- a
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );8 e& n1 p" v* ^- U1 E  h
  LRESULT lRes;( I# [+ ?$ r1 M0 I/ r
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );
" T5 @: v1 d" [; i+ ~6 T( h7 o- S) Z/ i: B. G( N
  CComPtr < IHTMLDocument2 > spDoc;
9 T! h* c3 [9 V, R/ K2 p   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );$ C2 ?+ r: Z/ E* x) f8 j1 x
  if ( FAILED ( hr ) )   return;) U6 A8 z9 h' {- y- Y  i
6 J% x0 d/ F: T4 j. d: i
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
2 J! o4 z0 e9 Z" S& g}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 23:10 , Processed in 0.015713 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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