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

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

[复制链接]
发表于 2005-4-20 17:46:13 | 显示全部楼层 |阅读模式
  根据IE浏览器的运行方式,有多种不同的方式可以获取文档指针。8 t3 v0 `: |/ `" G* @. L( T

" C& Q& K. K4 E* m9 v5 w7 o  <1> 如果你在程序中使用MFC的 CHtmlView 视来浏览网页。! Y7 ~; f5 n: W9 Y/ z- z* q' Q9 y- Y
       取得文档的方法最简单,调用 CHtmlView::GetHtmlDocument() 函数。
$ E8 z, X$ ?7 x/ m: x0 X1 o8 M' z  <2> 如果你的程序中使用了“Web 浏览器” 的ActiveX 控件。9 }# [3 z7 J5 A& \$ Z
       取得文档的方法也比较简单,调用 CWebBrowser2::GetDocument() 函数。* T- L6 V: G5 Q9 M2 H% m4 L0 y
  <3> 如果你的程序是用 ATL 写的 ActiveX 控件。! @5 ~3 ~! y8 x3 p6 t
       那么需要调用 IOleClientSite::GetContainer 得到 IOleContainer 接口,然后就可以通过 QueryInterface() 查询得到 IHTMLDocument2 的接口。主要代码如下:
4 Q' ^  Q' R# b: G- w
4 o" }5 u) J8 j% P8 u- MCComPtr < IOleContainer > spContainer;% D& x+ {  S: Z* Z/ x: P7 a
m_spClientSite->GetContainer( &spContainer );/ }+ n9 {4 _% D4 T$ S$ H
CComQIPtr < IHTMLDocument2 > spDoc = spContainer;3 ?: F3 N8 K& N% J1 i# z
if ( spDoc )
+ o" O! }% J4 x9 T{
4 w2 U" y/ ~3 L8 `8 z, E# O. Q- ^! r     // 已经得到了 IHTMLDocument2 的接口指针. s6 m3 R# S1 [6 K+ M/ ^
}+ F7 s& C. E8 [0 D
1 C9 s* |! ?* K8 p! X5 ^* t5 ^
  <4> 如果你的程序是用 MFC 写的 ActiveX 控件。
4 O+ F$ s7 H  u; s# _1 [        那么需要调用 COleControl::GetClientSite() 得到 IOleContainer 接口,然后的操作和<3>是一致的了。
+ W$ @% H% d$ c( E! w- U& N& T  <5> IE 浏览器作为独立的进程正在运行。4 l7 V7 d: e, a
       每个运行的浏览器(IE 和 资源浏览器)都会在 ShellWindows 中进行登记,因此我们要通过 IShellWindows 取得实例(示例程序中使用的就是这个方法)。主要代码如下:! T  f6 N" ?" z

) T7 j0 W$ D! {) [#include < atlbase.h >- v) F! Z; m7 @- n
#include < mshtml.h >
) ]) V2 c0 M% P# K' E7 x% t
+ G% T- s+ \2 Z# i/ ]void FindFromShell()
2 F3 w' w" t4 _# G: y2 h{
" n, _0 x; e9 E) }/ A: U6 J+ w0 a   CComPtr< IShellWindows > spShellWin;
, D0 N7 V! P/ o  M1 Z1 ~   HRESULT hr = spShellWin.CoCreateInstance( CLSID_ShellWindows );
* D8 c, u% r- _( Y   if ( FAILED( hr ) )    return;
$ j5 }4 Y9 d6 N  C- e) l$ v) |
" K- k" P* g( F$ ^% W   long nCount=0;
0 B, ^" y" m7 A8 b   spShellWin->get_Count(&nCount);   // 取得浏览器实例个数, U4 K  ~$ m$ a  V
6 Y2 @& S, i5 g8 W( A
  for(long i=0; i<nCount; i++)
$ h/ Y5 ~8 t: s0 \0 z* T0 `" }3 t       {
6 h9 q0 o+ j% o1 |# y- r; a                CComPtr< IDispatch > spDisp;* E* o4 L# ?- o
     hr=spShellWin->Item(CComVariant( i ), &spDisp );
5 w- u; T$ D4 f' x      if ( FAILED( hr ) )   continue;
$ z1 b; q8 z/ i8 m9 N( R) W* q1 e) K% o; i$ _! u# k. h
     CComQIPtr< IWebBrowser2 > spBrowser = spDisp;
' I3 J$ f. k* o# l& S  c( [      if ( !spBrowser )     continue;
2 `0 v! f6 z0 U4 ?: w2 z! _  X0 F  @0 k/ t) q/ a# S
     spDisp.Release();/ P+ F5 b4 u( |8 j& ~* q- k: F
     hr = spBrowser->get_Document( &spDisp );3 `5 c! }+ k/ @: D8 v% r9 `
     if ( FAILED ( hr ) )  continue;2 A! D& N4 A4 C7 v/ W- W" F

% f. X" u* l7 V0 ]0 s) e      CComQIPtr< IHTMLDocument2 > spDoc = spDisp;3 F* i4 _% q& p# ?8 M
     if ( !spDoc )         continue;8 o7 q3 r, Q& X' a* b

  |& B6 h7 B7 J  U      // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针2 w( V" a! d$ i) R
  }
; M/ y! c% Z- i$ r}
9 |) e2 s% {3 y8 a
( }( g( d6 W) T% \9 |7 G  <6> IE 浏览器控件被一个进程包装在一个子窗口中。那么你首先要得到那个进程的顶层窗口句柄(使用 FindWindow() 函数,或其它任何可行的方法),然后枚举所有子窗口,通过判断窗口类名是否是“Internet Explorer_Server”,从而得到浏览器的窗口句柄,再向窗口发消息取得文档的接口指针。主要代码如下: 5 L7 p5 W- ?- n' d2 C
/ F1 H5 u+ X0 y1 M
7 T* S2 d5 V7 X7 a. F2 K  S4 m
#include < atlbase.h >4 |5 I8 @9 E& r, ^% [/ Q4 I
#include < mshtml.h >
6 t0 Q8 B- q$ f1 s#include < oleacc.h >
) }0 ^1 o# t; a" T) a: g#pragma comment ( lib, "oleacc" )
5 ]( S3 h! A9 d$ N" y/ X' r4 f
; \# H0 V  v8 [0 @% mBOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)! c: o3 H+ _) r" Z4 t* w6 F
{9 U* h7 a6 q$ N6 \/ z* `
  TCHAR szClassName[100];
6 D/ x2 j2 l' u6 e. r2 f  K
! }5 c+ N. X4 X   ::GetClassName( hwnd,  &szClassName,  sizeof(szClassName) );$ B, e4 U- e$ a
  if ( _tcscmp( szClassName,  _T("Internet Explorer_Server") ) == 0 )
7 n( `+ ~# P+ q& A( g; J- t   {
# j+ k4 S+ l5 ?; I      *(HWND*)lParam = hwnd;' @% S. F* D0 h6 A. k5 z: e4 l
     return FALSE;      // 找到第一个 IE 控件的子窗口就停止- e4 M& O3 j7 c4 d1 d0 T
  }- s. g$ J! g  d! k
  else   return TRUE;      // 继续枚举子窗口
1 v' U5 q  a+ K" Q3 a' B% W& D. n: N};
5 p/ E5 k/ h' h  ^( d5 a  t% M
7 e0 p9 j2 V  Zvoid FindFromHwnd(HWND hWnd) ! {3 O; }5 B8 M1 |0 R
{7 z' j0 _# b8 l1 \5 r- T0 @
  HWND hWndChild=NULL;3 n/ a- {! c7 B$ C, M& \
  ::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );/ T7 s: ^- n5 W! E4 R
  if(NULL == hWndChild)   return;9 x$ ^; |) i0 A1 j) n

: n5 J  c! v) ]1 z( _   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );) C2 Y& O$ I* r9 k. i  p2 V
  LRESULT lRes;
8 G3 ~- L$ p$ h- m   ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*) &lRes );: D3 Z+ |2 {6 u! t- v
+ T, w! r0 x: q7 J, x
  CComPtr < IHTMLDocument2 > spDoc;
# [* l4 e- Z% _( d# l$ {   HRESULT hr = ::ObjectFromLresult ( lRes, IID_IHTMLDocument2, 0 , (LPVOID *) &spDoc );' J1 {$ G6 E' i) q' D1 R. V
  if ( FAILED ( hr ) )   return;
% x# E& @, z# T& L. h( X- T
5 F: S, G$ ^  L& S6 s- o1 D   // 程序运行到此,已经找到了 IHTMLDocument2 的接口指针
3 `" |: M  s5 l; H}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 16:30 , Processed in 0.017248 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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