long FXEmbedApp::dispatchEvent(FXID hwnd, unsigned int iMsg, unsigned int wParam, long lParam) { FXbool processed = FALSE; long result; switch(iMsg) { case WM_ACTIVATE: { if(wParam != WA_INACTIVE) { // Activate // Dispatch this event to the original FXApp message proc and then fool it // that we have got a WM_SETFOCUS event, in order the focusWindow member to be correctly updated result = FXApp::dispatchEvent(hwnd, iMsg, wParam, lParam); FXApp::dispatchEvent(hwnd, WM_SETFOCUS, lParam, 0); } else { // Deactivate // Dispatch this event to the original FXApp message proc and then fool it // that we have got a WM_KILLFOCUS event, in ordser the focusWindow member to be correctly updated result = FXApp::dispatchEvent(hwnd, iMsg, wParam, lParam); FXApp::dispatchEvent(hwnd, WM_KILLFOCUS, lParam, 0); } processed = TRUE; break; } case WM_MOUSEACTIVATE: { // This message is processed in order for us to know if an embedded window is about to // receive the input focus. // If so, we set Fox's logical focus to the FXEmbedderWindow parent, so when the // main window is deactivated and then activated again, FXEmbedderWindow will get FocusIn event // and will return the focus to the embedded window // // The way the activated window is detected is a bit hackish, but I don't think there is a way around it POINT pt; if(GetCursorPos(&pt) == 0) { DWORD pos = GetMessagePos(); pt.x = (short)(pos&0xFFFF); pt.y = (short)(pos >> 16); } HWND hitWindow = WindowFromPoint(pt); FXWindow* window = NULL; if(findWindowWithId(hitWindow) == NULL) { // OK. not a Fox window HWND hwnd = hitWindow; while(window == NULL) { if((hwnd = GetParent(hwnd)) == 0) break; window = findWindowWithId(hwnd); } } if(window != NULL) window->setFocus(); else { if(getFocusWindow() != NULL) { HWND winFocusWindowId = ::GetFocus(); HWND foxFocusWindowId = (HWND)getFocusWindow()->id(); if(foxFocusWindowId != winFocusWindowId && IsChild(foxFocusWindowId, winFocusWindowId)) // Return the focus to the top window ::SetFocus(foxFocusWindowId); } } break; } case WM_SETFOCUS: case WM_KILLFOCUS: { // We *should not* delegate these to the original FXApp message proc, because // we can now have focus set inside embedded window, which FXApp cannot deal with because // it expects the focus to be always in the main window // // Fox should really handle WM_ACTIVATE instead of WM_SETFOCUS/WM_KILLFOCUS result = DefWindowProc((HWND)hwnd, iMsg, wParam, lParam); processed = TRUE; break; } case TRAYMESSAGE: { FXWindow* tray = findWindowWithId(hwnd); if(tray != NULL) { switch(lParam) { case WM_LBUTTONDOWN: SetForegroundWindow((HWND)tray->id()); tray->handle(tray, FXSEL(SEL_COMMAND, FXTray::ID_TRAY_CLICKED), NULL); break; case WM_LBUTTONDBLCLK: case WM_RBUTTONDBLCLK: SetForegroundWindow((HWND)tray->id()); tray->handle(tray, FXSEL(SEL_COMMAND, FXTray::ID_TRAY_DBLCLICKED), NULL); break; case WM_RBUTTONUP: SetForegroundWindow((HWND)tray->id()); tray->handle(tray, FXSEL(SEL_COMMAND, FXTray::ID_TRAY_CONTEXT_MENU), NULL); break; } processed = TRUE; } break; } }