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
2009-09-06 12:31:43
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
2009-09-14 20:43:06
Perhaps the callback function needs to be static... Worked for me.
Neko
2009-09-17 12:56:54
yeah, the callback function is static. Wouldn't work in any other way.
GotAmye
2009-09-17 19:20:12
If it works, accept the answer ;)
Neko
2009-09-21 13:06:12
No, i meant that the code wouldn't compile without making the OnWindowMessage static. But, the move event still isn't being handled :(
GotAmye
2009-09-21 20:38:59
Hmmm strange. Perhaps you should post the relevant code here so we could scrutinize it...
Neko
2009-09-22 08:03:16
Now I see that the code doesn't work in IE8... It worked fine in IE7 :(
Neko
2009-10-27 09:26:35
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
2009-09-22 20:28:10