关于 IHTMLDocument2

MSDN上面找到的代码,一起贴上来,

还有说一下我用的是WIN7+VS2008,IE的窗口句柄是直接用Spy++得到的,

BOOL CALLBACK MyEnumChildProc(HWND hwnd,LPARAM lParam)
{
  TCHAR buf[100];

  ::GetClassName( hwnd, (LPTSTR)&buf, 100 );
  if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 )
  {
  *(HWND*)lParam = hwnd;
  return FALSE;
  }
  else
  return TRUE;
}

void OnGetDocInterface(HWND hWnd) 
{
  CoInitialize( NULL );
  // Explicitly load MSAA so we know if it's installed
  HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
  if ( hInst != NULL )
  {
  if ( hWnd != NULL )
  {
  HWND hWndChild=NULL;
  // Get 1st document window
  ::EnumChildWindows( hWnd, MyEnumChildProc, (LPARAM)&hWndChild );
  if ( hWndChild )
  {
  CComPtr< IHTMLDocument2> spDoc;
  LRESULT lRes;
   
  UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
  ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );

  LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, "ObjectFromLresult");
  if ( pfObjectFromLresult != NULL )
  {
  HRESULT hr;
  hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)&spDoc );
  if ( SUCCEEDED(hr))
  {
  // Change background color to red
  spDoc->put_bgColor( CComVariant("red") );
  }
  }
  } // else document not ready
  } // else Internet Explorer is not running
  ::FreeLibrary( hInst );
  } // else Active Accessibility is not installed
  CoUninitialize();
} MSDN的解释:Neither clients nor servers should call this function.

实际上这个API本来不应该公开,它只能用于当前线程中创建的组件,跨线程不能用,跨进程更不用说。
引用 4 楼 jameshooo 的回复:
ObjectFromLresult 仅限项目内部使用, MSDN的解释:Neither clients nor servers should call this function.

实际上这个API本来不应该公开,它只能用于当前线程中创建的组件,跨线程不能用,跨进程更不用说。

你这个说法是不是有点太离谱了,连跨线程都不能用,我以前也想过这个问题,后来改为DLL注入还是不行,难道真的不能跨线程使用,

要真的象你这样说的话,那岂不是没有办法去获取别的窗口的 IHTMLDocument2接口了??

不知道还有没有其他的办法呢??
引用 7 楼 jameshooo 的回复:
道理很简单,当客户端向窗口发送 WM_HTML_GETOBJECT 消息时,窗口把组件(注意这个组件属于窗口所在线程)的 IUnknown* 转换成 LRESULT 返回给客户端,然后 ObjectFromLresult 把 LRESULT 转换回 IUnknown* 之后调用其 QueryInterface 方法查询需要的接口。过程决定结果,一个线程中的接口指针未经列集传递给其它线程或进程,这个接口还能用吗?

事实上 WM_HTML_GETOBJECT 不是标准消息,并不被微软支持,它是开发库内部定义的消息。标准消息是跟 IAccessible 有关的 WM_GETOBJECT 消息,这个消息能被系统自动列集,所以可以跨线程调用 ObjectFromLresult 并获得正确的结果。

我都被你说糊涂了,你前面不是说不能跨线程使用么,怎么现在又改成能呢,
经过单步执行,发现ObjectFromResult这个函数可以成功执行,但是返回的接口就是不能用,这样看来这个方法真的行不能,不知道还有没有其他的办法呢,我只是想获得Internet Explorer_Server里面的html代码,请指点
HRESULT CMyQQGameToolDlg::GetIHTMLDocument2FromHWND( IHTMLDocument2 ** pDoc2) { LRESULT lRes; UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") ); ::SendMessageTimeout(m_hIE, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes ); LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( m_hInstMSAA, "ObjectFromLresult"); if (NULL == pfObjectFromLresult) { ... } HRESULT hr; hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)pDoc2 ); if (FAILED(hr)) { ... } return S_OK; } 调用处的代码 // GET IE hwnd ... CComPtr< IHTMLDocument2> spDoc2; HRESULT hr = E_FAIL; hr = GetIHTMLDocument2FromHWND(&spDoc2); / // 直接操作spDoc2会有异常! // 再QI一次获取另外的接口就可以操作了 // CComQIPtr<IHTMLDocument3> spDoc3 = spDoc2; hr = spDoc3->getElementById(...
引用 11 楼 skyxie 的回复:

事实上,这种方法是可以用的,获取【其他进程】的doc进行操作没有任何问题!

我曾经用这种方法写过一个自动玩qq网页游戏怪物对对碰的辅助工具(使用IE打开qq怪物对对碰游戏,然后用工具选中该IE窗口,就可以自动玩)

C/C++ code

HRESULT CMyQQGameToolDlg::GetIHTMLDocument2FromHWND( IHTMLDocument2 ** pDo……


确实如你所说,再QI一次就可以了,呵呵
引用 12 楼 grany 的回复:

转一篇文章,希望对你有用
不要在线程之间传递原始接口指针我咨询的首批COM项目之一就涉及到一个包含100,000行代码的分布式应用程序,该程序是由美国西海岸的一个大型软件公司编写的。该应用程序在多个机器上创建了数十个COM对象,并从客户端进程启动的背景线程中调用这些对象。开发小组遇到问题了,调用要么消失得无影无踪,要么在没有明显原因的情况下失败。他们给我演示的最惊人的症状是:当一个调用无法返回……

虽然这篇文章中所说的方法我用不上,不过还是长见识了,相信以后一定用得上的,
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号世纪乐知(北京)网络技术有限公司 提供技术支持Copyright © 1999-2010, CSDN.NET, All Rights Reserved




引文来源  兄弟帮忙看一段获取IHTMLDocument2接口的代码,MSDN上面找的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值