示例#1
0
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;
		}
	}