can now also handle the case where menus is opened, client area of
[freeglut] / src / mswin / fg_main_mswin.c
index 15e9102..a992b2b 100644 (file)
@@ -239,6 +239,22 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     /* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0,
              uMsg, wParam, lParam ); */
 
+    /* events only sent to main window. Check if the current window that the mouse
+       is over is a child window and if so, make sure we call the callback on that
+       child instead.
+    */
+    if (window && window->Children.First)
+    {
+        POINT mouse_pos;
+        SFG_WindowHandleType hwnd;
+
+        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 */
+            window = fgWindowByHandle(hwnd);
+    }
+
     if ( window )
     {
       fgState.Modifiers = fgPlatformGetModifiers( );
@@ -477,14 +493,39 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         break;
 
     case WM_KILLFOCUS:
-/*        printf("WM_KILLFOCUS: %p\n", window ); */
-        lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
-        INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
-
-        if( window->IsMenu &&
-            window->ActiveMenu && window->ActiveMenu->IsActive )
-            fgUpdateMenuHighlight( window->ActiveMenu );
+        {
+            SFG_Menu* menu = NULL;
+/*            printf("WM_KILLFOCUS (ismenu: %i): %p\n", window->IsMenu, window ); */
+            lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
+            INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
 
+            /* 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.CurrentMenu )
+                menu = fgGetActiveMenu();
+            
+            if ( menu )
+            {
+                SFG_Window* wnd = NULL;
+                HWND hwnd = GetForegroundWindow();  /* Get window with current focus */
+                if (hwnd)
+                    /* See if its one of our windows */
+                    wnd = fgWindowByHandle(hwnd);
+
+                if (!hwnd || !wnd)
+                    /* User switched to another application*/
+                    fgDeactivateMenu(menu->ParentWindow);
+                else if (
+                    ( wnd->IsMenu && wnd->ActiveMenu && wnd->ActiveMenu->ParentWindow!=menu->ParentWindow) ||    /* Make sure we don't kill the menu when trying to enter a submenu */
+                    (!wnd->IsMenu && wnd!=menu->ParentWindow)
+                    )
+                    /* User switched to another FreeGLUT window */
+                    fgDeactivateMenu(menu->ParentWindow);
+            }
+        }
         break;
 
 #if 0
@@ -552,7 +593,6 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
             fgUpdateMenuHighlight( window->ActiveMenu );
             break;
         }
-        SetFocus(window->Window.Handle);
 
         fgState.Modifiers = fgPlatformGetModifiers( );
 
@@ -679,8 +719,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
     }
     break;
 
-    case 0x020a:
-        /* Should be WM_MOUSEWHEEL but my compiler doesn't recognize it */
+    case WM_MOUSEWHEEL:
     {
         int wheel_number = LOWORD( wParam );
         short ticks = ( short )HIWORD( wParam );
@@ -752,6 +791,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
         int keypress = -1;
         POINT mouse_pos ;
 
+
         if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) )
             break;