我在用ATL开发BHO时遇到这样的一个功能需求:需要监视IE窗口移动并在页面内容中做出改变。
在实际开发中,DISPID_WINDOWMOVE微软的mshtml库并未实现它,这个event根本没有fire。
然后我有想通过HOOK的方式来监视还是无法成功。
我贴出部分代码

                long m_pWebBrowserHwnd;
mWebBrowser2->get_HWND(&m_pWebBrowserHwnd);
if(m_pWebBrowserHwnd)
{ int idHook = WH_CALLWNDPROC; // Type of hook: all Window calls
HOOKPROC hookProc = OnWindowMessage; // Procedure to be called
HINSTANCE hMod = NULL; // DLL to monitor
DWORD dwThreadId = GetWindowThreadProcessId((HWND)m_pWebBrowserHwnd,NULL); // IE Thread to monitor
HHOOK m_ResizeHook = SetWindowsHookEx(idHook, hookProc, hMod, 0); 
::MessageBox(NULL,_T("获取句柄") ,_T("Warning"),MB_ICONSTOP);
}
LRESULT CALLBACK OnWindowMessage(int nCode, WPARAM wParam, LPARAM lParam)
{LRESULT result = CallNextHookEx(NULL, nCode, wParam, lParam);
::MessageBox(NULL,_T("窗口移动了") ,_T("Warning"),MB_ICONSTOP);
if( (lParam!=NULL) && (nCode == HC_ACTION))
{
CWPSTRUCT *CwpStruct = (CWPSTRUCT *) lParam;
switch(CwpStruct->message)
{
case WM_MOVE:
HWND manipluatedHWND = CwpStruct->hwnd;
        //Code to execute when window moves
::MessageBox(NULL,_T("窗口移动了") ,_T("Warning"),MB_ICONSTOP);
break;
}
}
return S_OK;
}经过测试仍然无法获得IE窗口移动的句柄。
请问有什么好办法解决这个问题?能贴出部分代码更好,谢谢。ATLBHO

解决方案 »

  1.   

    思路本来是不错,但是你找错了窗口,你找到的是子窗口,子窗口相对于父窗口来说位置基本上永远不会改变,你应该找IE主窗口(顶级窗口),就可以捕捉到窗口移动。另一个问题是IE的版本,IE8开始支持多进程浏览,BHO是跟每个主页面的IWebBrowser2接口一一对应的,而且跟IWebBrowser2处于相同的进程,这意味着BHO代码执行的进程跟主窗口进程不同,如果进程不同,就不能用子类化方式拦截窗口消息,必须想办法让拦截消息的代码跟主窗口属于同一个进程,这可能需要SetWindowHook或者线程远程注入的方式来做。当然,如果觉得繁琐或者难以搞定,大可以不拦截消息,而是通过定时器周期读取主窗口位置,自己判断位置是否变化了。
      

  2.   

    看来还是从用定时器入手的好,ATL刚刚入门,还有很多不懂,谢谢LS这位兄台。
      

  3.   

    BHO做不到,可以SubClass浏览器窗口的消息处理,拦截WM_MOVE WM_SIZE消息。
      

  4.   

    我就是要做一个BHO,间接的办法也行