SFG_Window* window;
PAINTSTRUCT ps;
LRESULT lRet = 1;
+ GLboolean gotChild = GL_FALSE;
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ;
/* 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->Parent)
+ gotChild = GL_TRUE;
+ }
+ }
+
if ( window )
{
+ fgState.Modifiers = fgPlatformGetModifiers( );
+
/* Checking for CTRL, ALT, and SHIFT key positions: Key Down! */
if ( !lControl && GetAsyncKeyState ( VK_LCONTROL ) )
{
rAlt = 0;
}
+
+ fgState.Modifiers = INVALID_MODIFIERS;
}
switch( uMsg )
case WM_SETFOCUS:
/* printf("WM_SETFOCUS: %p\n", window ); */
+ if (gotChild)
+ /* If child should have focus instead, set it here. */
+ SetFocus(window->Window.Handle);
+
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
- UpdateWindow ( hWnd );
+ UpdateWindow ( hWnd );
+ if (gotChild)
+ UpdateWindow ( window->Window.Handle );
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;
+/* 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 );
+ /* 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 && wnd!=menu->ParentWindow) /* Make sure we don't kill the menu when trying to enter a submenu */
+ /* User switched to another FreeGLUT window */
+ fgDeactivateMenu(menu->ParentWindow);
+ }
+ }
break;
#if 0
fgUpdateMenuHighlight( window->ActiveMenu );
break;
}
- SetFocus(window->Window.Handle);
fgState.Modifiers = fgPlatformGetModifiers( );
}
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 );
/*
* XXX Should use WHEEL_DELTA instead of 120
*/
- if ( abs ( fgState.MouseWheelTicks ) > 120 )
+ if ( abs ( fgState.MouseWheelTicks ) >= 120 )
{
int direction = ( fgState.MouseWheelTicks > 0 ) ? 1 : -1;
/*
* XXX Should use WHEEL_DELTA instead of 120
*/
- while( abs ( fgState.MouseWheelTicks ) > 120 )
+ while( abs ( fgState.MouseWheelTicks ) >= 120 )
{
if( FETCH_WCB( *window, MouseWheel ) )
INVOKE_WCB( *window, MouseWheel,
int keypress = -1;
POINT mouse_pos ;
+
if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) )
break;
KEY( VK_RIGHT, GLUT_KEY_RIGHT );
KEY( VK_DOWN, GLUT_KEY_DOWN );
KEY( VK_INSERT, GLUT_KEY_INSERT );
- KEY( VK_LCONTROL, GLUT_KEY_CTRL_L );
- KEY( VK_RCONTROL, GLUT_KEY_CTRL_R );
- KEY( VK_LSHIFT, GLUT_KEY_SHIFT_L );
- KEY( VK_RSHIFT, GLUT_KEY_SHIFT_R );
- KEY( VK_LMENU, GLUT_KEY_ALT_L );
- KEY( VK_RMENU, GLUT_KEY_ALT_R );
+
+ case VK_LCONTROL: case VK_RCONTROL: case VK_CONTROL:
+ case VK_LSHIFT: case VK_RSHIFT: case VK_SHIFT:
+ case VK_LMENU: case VK_RMENU: case VK_MENU:
+ /* These keypresses and releases are handled earlier in the function */
+ break;
case VK_DELETE:
/* The delete key should be treated as an ASCII keypress: */
KEY( VK_RIGHT, GLUT_KEY_RIGHT );
KEY( VK_DOWN, GLUT_KEY_DOWN );
KEY( VK_INSERT, GLUT_KEY_INSERT );
- KEY( VK_LCONTROL, GLUT_KEY_CTRL_L );
- KEY( VK_RCONTROL, GLUT_KEY_CTRL_R );
- KEY( VK_LSHIFT, GLUT_KEY_SHIFT_L );
- KEY( VK_RSHIFT, GLUT_KEY_SHIFT_R );
- KEY( VK_LMENU, GLUT_KEY_ALT_L );
- KEY( VK_RMENU, GLUT_KEY_ALT_R );
+
+ case VK_LCONTROL: case VK_RCONTROL: case VK_CONTROL:
+ case VK_LSHIFT: case VK_RSHIFT: case VK_SHIFT:
+ case VK_LMENU: case VK_RMENU: case VK_MENU:
+ /* These keypresses and releases are handled earlier in the function */
+ break;
case VK_DELETE:
/* The delete key should be treated as an ASCII keypress: */