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