static unsigned char lControl = 0, rControl = 0, lShift = 0,
rShift = 0, lAlt = 0, rAlt = 0;
- SFG_Window* window;
+ SFG_Window *window, *child_window = NULL;
PAINTSTRUCT ps;
LRESULT lRet = 1;
/* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0,
uMsg, wParam, lParam ); */
+ /* Some events only sent to main window. Check if the current window that
+ * the mouse is over is a child window. Below when handling some messages,
+ * we make sure that we process callbacks on the child window instead.
+ * This mirrors how GLUT does things.
+ */
+ if (window && window->Children.First)
+ {
+ POINT mouse_pos;
+ SFG_WindowHandleType hwnd;
+ SFG_Window* temp_window;
+
+ GetCursorPos( &mouse_pos );
+ ScreenToClient( window->Window.Handle, &mouse_pos );
+ hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos);
+ if (hwnd) /* can be NULL if mouse outside parent by the time we get here */
+ {
+ temp_window = fgWindowByHandle(hwnd);
+ if (temp_window->Parent) /* Verify we got a child window */
+ child_window = temp_window;
+ }
+ }
+
if ( window )
{
+ SFG_Window* temp_window = child_window?child_window:window;
+
fgState.Modifiers = fgPlatformGetModifiers( );
/* Checking for CTRL, ALT, and SHIFT key positions: Key Down! */
if ( !lControl && GetAsyncKeyState ( VK_LCONTROL ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lControl = 1;
if ( !rControl && GetAsyncKeyState ( VK_RCONTROL ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rControl = 1;
if ( !lShift && GetAsyncKeyState ( VK_LSHIFT ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lShift = 1;
if ( !rShift && GetAsyncKeyState ( VK_RSHIFT ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rShift = 1;
if ( !lAlt && GetAsyncKeyState ( VK_LMENU ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lAlt = 1;
if ( !rAlt && GetAsyncKeyState ( VK_RMENU ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rAlt = 1;
/* Checking for CTRL, ALT, and SHIFT key positions: Key Up! */
if ( lControl && !GetAsyncKeyState ( VK_LCONTROL ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lControl = 0;
if ( rControl && !GetAsyncKeyState ( VK_RCONTROL ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rControl = 0;
if ( lShift && !GetAsyncKeyState ( VK_LSHIFT ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lShift = 0;
if ( rShift && !GetAsyncKeyState ( VK_RSHIFT ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rShift = 0;
if ( lAlt && !GetAsyncKeyState ( VK_LMENU ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lAlt = 0;
if ( rAlt && !GetAsyncKeyState ( VK_RMENU ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rAlt = 0;
case WM_SETFOCUS:
/* printf("WM_SETFOCUS: %p\n", window ); */
+
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
- INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
- UpdateWindow ( hWnd );
+ if (child_window)
+ {
+ /* If child should have focus instead, set it here. */
+ SetFocus(child_window->Window.Handle);
+ SetActiveWindow( child_window->Window.Handle );
+ INVOKE_WCB( *child_window, Entry, ( GLUT_ENTERED ) );
+ UpdateWindow ( child_window->Window.Handle );
+ }
+ else
+ {
+ SetActiveWindow( window->Window.Handle );
+ INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
+ }
+ /* Always request update on main window to be safe */
+ UpdateWindow ( hWnd );
+
break;
case WM_KILLFOCUS:
-/* printf("WM_KILLFOCUS: %p\n", window ); */
- lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
- INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
+ {
+ SFG_Menu* menu = NULL;
+ SFG_Window* saved_window = fgStructure.CurrentWindow;
+/* printf("WM_KILLFOCUS: %p\n", window ); */
+ lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+ INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
+ fgSetWindow(saved_window);
- if( window->IsMenu &&
- window->ActiveMenu && window->ActiveMenu->IsActive )
- fgUpdateMenuHighlight( window->ActiveMenu );
+ /* If we have an open menu, see if the open menu should be closed
+ * when focus was lost because user either switched
+ * application or FreeGLUT window (if one is running multiple
+ * windows). If so, close menu the active menu.
+ */
+ if ( fgStructure.Menus.First )
+ menu = fgGetActiveMenu();
+ if ( menu )
+ {
+ SFG_Window* wnd = NULL;
+ HWND hwnd = GetFocus(); /* Get window with current focus - NULL for non freeglut windows */
+ if (hwnd)
+ /* See which of our windows it is */
+ wnd = fgWindowByHandle(hwnd);
+
+ if (!hwnd || !wnd)
+ /* User switched to another application*/
+ fgDeactivateMenu(menu->ParentWindow);
+ else if (!wnd->IsMenu) /* Make sure we don't kill the menu when trying to enter a submenu */
+ {
+ if (wnd!=menu->ParentWindow)
+ /* User switched to another FreeGLUT window */
+ fgDeactivateMenu(menu->ParentWindow);
+ else
+ {
+ /* Check if focus lost because non-client area of
+ * window was pressed (pressing on client area is
+ * handled in fgCheckActiveMenu)
+ */
+ POINT mouse_pos;
+ RECT clientArea = fghGetClientArea(menu->ParentWindow, GL_FALSE);
+ GetCursorPos(&mouse_pos);
+ if ( !PtInRect( &clientArea, mouse_pos ) )
+ fgDeactivateMenu(menu->ParentWindow);
+ }
+ }
+ }
+ }
break;
#if 0
fgUpdateMenuHighlight( window->ActiveMenu );
break;
}
- SetFocus(window->Window.Handle);
fgState.Modifiers = fgPlatformGetModifiers( );
int keypress = -1;
POINT mouse_pos ;
+ if (child_window)
+ window = child_window;
+
if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) )
break;
int keypress = -1;
POINT mouse_pos;
+ if (child_window)
+ window = child_window;
+
/*
* Remember the current modifiers state. This is done here in order
* to make sure the VK_DELETE keyboard callback is executed properly.
case WM_SYSCHAR:
case WM_CHAR:
{
+ if (child_window)
+ window = child_window;
+
if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) )
break;