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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。! g# g3 r0 e5 H3 z2 e
" P$ N# w& h; f, |5 Y) E
  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。
' l3 |" y: t9 J! r1 _        取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。9 u! U( l" M3 z- _- }
  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。5 ?, L; a( ]) A' J* c0 _( k, J
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。, R( R3 I- @+ {6 r
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。
. d6 ~+ ^- i. @* i        那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:   v  j* \3 o7 V# J7 I/ C5 J; N

: w+ {- L' d+ ~# mCComPtr < IOleContainer > spContainer;2 _6 j  I' y( E* D5 [
m_spClientSite->GetContainer( &spContainer );  u# A; _7 e/ ?: \  C' @: e+ ]7 t
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;  K8 y( E! q( {; t
if ( spDoc )
0 ^# G/ f3 U% d{' k6 \) s% O# h
    // 已经得到了 IHTMLDocument2 的接口指针6 P8 j* G! q2 X' O, q
}
; j, u- \9 a0 S' l0 P2 n4 d
4 p& w5 ^. d/ Y1 e  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。! Q0 i# P6 u7 c6 ?6 ]- y
       那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。* q$ m  \* ?* j" _
  <5> IE 浏览器作为独立的进程正在运行。
% {6 ~- f; O5 V7 R        每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:
1 i) ^+ V2 O: W  K; m, B
$ ]# o7 W2 |5 Q& U1 [% I+ e#include < atlbase.h ># k* k! c. p5 L# E+ g& R9 Z$ s, R
#include < mshtml.h >+ K4 m9 A! j6 Q: M7 x/ t

1 E$ ^# q# M, W2 [( z: V  mvoid FindFromShell()
7 k! a6 G  ?/ E/ J{% S( Q' a; M+ S$ B
  CComPtr< IShellWindows > spShellWin;
3 N, f) \; W0 C' G$ b2 z, L4 r   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );6 R% r" W( J2 R  M' X- R1 O
  if ( FAILED( hr ) )    return;0 I' z& P" q1 E# p+ [6 u( M
2 Z! K. M5 n# N0 F* w" N
  long nCount=0;
" {4 c5 h0 u) g. B6 ~   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数
# j' E1 ^. `  B( x0 E5 R+ R  b3 Z9 s% [$ s( l# m
  for(long i=0; i<nCount; i++)8 K1 z) |% E" p; ^7 ?
      {: V' [+ f7 A; v7 q
               CComPtr< IDispatch > spDisp;0 t9 ~& s, w7 S& P' [! E
     hr=spShellWin->Item(CComVariant( i ), &spDisp );+ A' s  I+ G; Z5 h! K1 d
     if ( FAILED( hr ) )   continue;; C* n# G- v7 b$ E( |
2 d/ X7 d, e  a0 S9 U7 |9 ~4 p/ w
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
( N: Q! `6 j4 o$ ?8 g, F      if ( !spBrowser )     continue;: l+ U% m: G6 D! k

; ^9 Y; {0 `2 P/ z5 m% R  r/ m& ?, l      spDisp.Release();, k& Q0 \; K, ]6 p0 S
     hr = spBrowser->get_Document( &spDisp );
( R( D* j$ s! U% Z      if ( FAILED ( hr ) )  continue;
$ \: a+ S7 d" [$ F& v- t8 V
6 O7 }1 A- q( l' @. y/ q      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;. y0 {$ M; {' w  n) b4 m
     if ( !spDoc )         continue;  E7 N. E+ N2 f3 T

+ @' n) b2 ]3 F: {& \8 T      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 X; G3 Y3 A# i/ q5 ]1 r9 h/ Z
  }
/ N2 {+ ^5 J7 T) o* h- M}' Q0 Q( E) q5 Y

( ?6 N  l$ ~- Q. S* U. @  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下:
, ^& D; t. q. Y& C# A5 K2 N
; S% z) o# [. U
7 ]8 o; g+ Z9 {# ^9 \  x#include < atlbase.h >
0 G7 |! E# E: ^9 M7 X9 M#include < mshtml.h >
  |8 U6 U. e+ Y+ L9 i- E" n  F#include < oleacc.h >
( t+ B9 `' \7 S7 ~#pragma comment ( lib, "oleacc" )6 C  m/ C4 F1 J

  W$ m" I& [6 d% ^5 g8 Y9 zBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)- P$ @* V5 ?8 Y
{4 A/ T( j# b$ Q$ }7 t
  TCHAR szClassName[100];
1 c5 b( x- x  L; z( I; s
2 ?6 b7 c2 i3 d  a# N! X/ c2 T   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );
7 n% q& V6 a, q  x   if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
" k. [$ B* r: Y. v: l' s" Z$ r   {
8 l3 O; {3 B  ?; M      *(HWND*)lParam = hwnd;. e1 W+ A7 H$ h2 s
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止4 M5 l3 d  e- {9 A2 a
  }
8 H, ]( g, c) i8 r$ S' I   else   return TRUE;      // 继续枚举子窗口- I+ C7 ~. @, D6 o1 {) f' z
};
4 s2 K3 R' W. y: @* v1 Y- R: _; b
void FindFromHwnd(HWND hWnd) 3 v" ^$ `  w& e0 [3 [
{
- D+ j8 w/ f' `, |4 t6 y   HWND hWndChild=NULL;2 p3 [- S: L! f  K+ t  G
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );* M# e9 z6 r" g1 {$ N
  if(NULL == hWndChild)   return;  t6 V. v# X3 F
# T4 e. r% E+ X- R$ b; @2 p, z
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
! V( _4 x% {9 V( K7 F   LRESULT lRes;
6 _2 e) v# D  E- O1 B4 ]   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );" O! R6 ?" j3 y0 o5 |
5 H4 h1 Q2 N4 b" i- X
  CComPtr < IHTMLDocument2 > spDoc;0 f8 x6 x8 j" d: u3 g# G1 K$ ]5 N5 T
  HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );
: d& o; g1 W( }3 I( Z   if ( FAILED ( hr ) )   return;2 K  z& g' N7 A1 C) `1 e+ g/ Q
& T# [  `0 p! C" h+ D+ t) M6 i
  // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针/ B! j2 n& Z2 L! m8 Y  B8 [
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 06:23 , Processed in 0.034677 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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