views:

388

answers:

3

I want to handle window move events. My first try was to handle DWebBrowserEvents2::WindowSetHeight, WindowSetLeft, WindowSetTop and WindowSetWidth events, but for some reasons, these events didn't get fired at all.I've handled window resize by handling HTMLWindowEvents2::onresize. How would I handle when the window moves? I've also tried implementing IHTMLOMWindowServices, but its members are not called when window position changes. Are there any suggestions as to to what would be a good interface to implement? I'm creating an IE extension using ATL in Visual C++.

A: 

HTML window is not the right place. You need to go one level up to the browser window level, e.g.:

      // Get a handle for the IE window and set a hook for the window resize/move events
  m_spWebBrowser->get_HWND(reinterpret_cast<SHANDLE_PTR*>(&m_pWebBrowserHwnd));
  if(m_pWebBrowserHwnd)
  {
   int idHook = WH_CALLWNDPROC; // Type of hook: all Window calls
   HOOKPROC hookProc = MyClass::OnWindowMessage; // Procedure to be called
   HINSTANCE hMod = NULL; // DLL to monitor
   DWORD dwThreadId = GetWindowThreadProcessId(m_pWebBrowserHwnd,NULL); // IE Thread to monitor
   m_ResizeHook = SetWindowsHookEx(idHook, hookProc, hMod, dwThreadId); 
   Trace (L"Hook for window move/resize is set up");
  }

Then onWindowMessage handles the right message:

LRESULT CALLBACK MyClass::OnWindowMessage(int nCode, WPARAM wParam, LPARAM lParam)
{

LRESULT result = CallNextHookEx(NULL, nCode, wParam, lParam);

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
  break;
 }
}

Enjoy :)

Neko
Unfortunately, this trick didn't work. I set up the WindowsHook (that seems to be okay), but the callback function, OnWindowMessage is never called :(
GotAmye
Perhaps the callback function needs to be static... Worked for me.
Neko
yeah, the callback function is static. Wouldn't work in any other way.
GotAmye
If it works, accept the answer ;)
Neko
No, i meant that the code wouldn't compile without making the OnWindowMessage static. But, the move event still isn't being handled :(
GotAmye
Hmmm strange. Perhaps you should post the relevant code here so we could scrutinize it...
Neko
Now I see that the code doesn't work in IE8... It worked fine in IE7 :(
Neko
A: 

Okay, here's some rough code

class ATL_NO_VTABLE CHelloWorldBHO :
   public CComObjectRootEx<CComSingleThreadModel>,
   public CComCoClass<CHelloWorldBHO, &CLSID_HelloWorldBHO>,
   public IObjectWithSiteImpl<CHelloWorldBHO>,
   public IDispatchImpl<IHelloWorldBHO, &IID_IHelloWorldBHO, &LIBID_HelloWorldLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
   public IDispEventImpl<1, CHelloWorldBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>, 
  //Other interfaces here

{

         BEGIN_SINK_MAP(CHelloWorldBHO)
            SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)//Do stuff OnDocumentComplete
         END_SINK_MAP()

     void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL){
         //Do other stuff here
         SetUpWindowsHook();//This calls a function that sets a window hook, similar to the code that you've posted
     }

}

GotAmye
A: 

Handled the situation by using Timer. Not too elegant, but works!

GotAmye