BHO中如何读取showmodaldialog中的页面内容

      BHO是什么就不说了,在开发过程中有一个难点估计很多人都遇到,就是如何读取showmodaldialog中的页面内容。就我在网上找到的,基本都是2种办法:

      1、复写showmodaldialog方法,用自己的实现。

      2、实现newwindow3事件,具体可以参考(http://blog.chinaunix.net/uid-24862988-id-3685858.html)

      而言本人比较懒,加上技术不过关,以上2种方法实现起来都很麻烦,并且不好维护。于是就自己摸索了一个比较另类的方法。就是借助局部鼠标钩子来实现获取showmodaldialog中页面的内容。

      简单来说就是:鼠标钩子-->获取点击窗口句柄-->遍历其子窗口-->注册WM_HTML_GETOBJECT消息-->通过动态链接库OLEACC.DLL获取ObjectFromLresult函数地址-->调用函数获取IHTMLDocument2对象。

//1、CPP头文件定义一个钩子变量            
HHOOK h_Mouse = NULL;
//2、在SetSite中初始化和释放钩子
SetSite(IUnknown* pUnkSite)
{
	if (pUnkSite != NULL)
	{
		dwCookie = 1;
		HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
		if (SUCCEEDED(hr) && m_spWebBrowser)
		{
			hr = DispEventAdvise(m_spWebBrowser);
			if (SUCCEEDED(hr) && m_spWebBrowser)
			{
				h_Mouse = SetWindowsHookEx(WH_MOUSE, MouseProc, NULL, GetCurrentThreadId());  
				m_fAdvised = TRUE;
			}
		}
	}
	else
	{
		// Unregister event sink.
		if (m_fAdvised)
		{
			m_fAdvised = FALSE;
			if(h_Mouse)
			{
				UnhookWindowsHookEx(h_Mouse);
				h_Mouse = NULL;
			}
		}
	}
	//return S_OK;
	return IObjectWithSiteImpl<CEyeOnIE>::SetSite(pUnkSite);
}

3、定义鼠标钩子过程
LRESULT CALLBACK MouseProc(
  int nCode,      // hook code
  WPARAM wParam,  // message identifier
  LPARAM lParam   // mouse coordinates
)
{
	//在此写处理此消息的代码
	//返回非0值,表示我们已处理此鼠标消息了
	if (nCode == HC_ACTION)
	{
		if (wParam == WM_LBUTTONDOWN) 
		{	
			// 获取鼠标点中的对象句柄
			LPMOUSEHOOKSTRUCT pMouseHook = (MOUSEHOOKSTRUCT FAR *) lParam;
			if(pMouseHook)
			{
				HWND hWndChild = pMouseHook->hwnd;
				if(hWndChild)
				{
					TCHAR buf1[100];
					TCHAR buf2[100];

					HWND pHwnd = GetParent(hWndChild);

					if(pHwnd)
					{
						GetClassName(hWndChild, (LPTSTR)&buf1, 100);
						GetClassName(pHwnd, (LPTSTR)&buf2, 100);

						// 是模态窗口
						if (strcmp(buf1, "Internet Explorer_Server") == 0 && 
							strcmp(buf2, "Internet Explorer_TridentDlgFrame") == 0)
						{
							LRESULT lRes;

							UINT m_nMsg = RegisterWindowMessage("WM_HTML_GETOBJECT");
							LRESULT lResult = SendMessageTimeout(hWndChild, m_nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);

							if(lResult)
							{
								HINSTANCE m_hInst = LoadLibrary("OLEACC.DLL");
								LPFNOBJECTFROMLRESULT m_pfObjectFromLresult = 
									(LPFNOBJECTFROMLRESULT)::GetProcAddress(m_hInst, "ObjectFromLresult");

								if (m_pfObjectFromLresult != NULL)
								{
									HRESULT hr;
									CComQIPtr<IHTMLDocument2> spDoc;
									hr = (*m_pfObjectFromLresult)( lRes, IID_IHTMLDocument2, 0, (void**)&spDoc);
									if (SUCCEEDED(hr) && spDoc)
									{
										// 至此已找到了doc, 可以实现你想要的东东了.
									}
								}
								FreeLibrary(m_hInst); 
							}
						}
					}
				}
			}
		}
	}
nextCode:
	return CallNextHookEx(h_Mouse, nCode, wParam, lParam);
}

完毕。最后要提到是,代码中没有写过多的如何避免鼠标多次点击重复调用的问题,实现很多种方法,自己去摸索吧。


写在最后:

        BHO这种过时基本要被抛弃的东西,相信也没谁再去研究它了。无奈与之打交道多年,贸然放弃有点可惜,故此留作个记号,以示留念。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值