From 3eda17657740837287ddfcce49545311dd25422c Mon Sep 17 00:00:00 2001 From: dcnieho Date: Wed, 27 Feb 2013 07:52:55 +0000 Subject: [PATCH] Now implemented properly working mouse entry and exit (EntryFunc callback) support on windows git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1520 7f0cb862-5218-0410-a997-914c9d46530a --- freeglut/freeglut/src/fg_internal.h | 2 +- .../freeglut/src/mswin/fg_internal_mswin.h | 2 + freeglut/freeglut/src/mswin/fg_main_mswin.c | 37 +++++++++++++++---- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/freeglut/freeglut/src/fg_internal.h b/freeglut/freeglut/src/fg_internal.h index 6ac8ffe..85bb750 100644 --- a/freeglut/freeglut/src/fg_internal.h +++ b/freeglut/freeglut/src/fg_internal.h @@ -383,7 +383,7 @@ struct tagSFG_WindowState int Width; /* Window's width in pixels */ int Height; /* The same about the height */ - SFG_PlatformWindowState pWState; /* Window width/height (X11) or rectangle/style (Windows) from before a resize */ + SFG_PlatformWindowState pWState; /* Window width/height (X11) or rectangle/style (Windows) from before a resize, and other stuff only needed on specific platforms */ GLboolean Redisplay; /* Do we have to redisplay? */ GLboolean Visible; /* Is the window visible now */ diff --git a/freeglut/freeglut/src/mswin/fg_internal_mswin.h b/freeglut/freeglut/src/mswin/fg_internal_mswin.h index 21899b8..fb6b1b7 100644 --- a/freeglut/freeglut/src/mswin/fg_internal_mswin.h +++ b/freeglut/freeglut/src/mswin/fg_internal_mswin.h @@ -95,6 +95,8 @@ struct tagSFG_PlatformWindowState DWORD OldStyle; /* window style - stored before the window is made fullscreen */ DWORD OldStyleEx; /* window Ex style - stored before the window is made fullscreen */ BOOL OldMaximized; /* window maximized state - stored before the window is made fullscreen */ + + GLboolean MouseTracking; /* Needed for generating GLUT_ENTERED and GLUT_LEFT entry func callbacks on windows */ }; diff --git a/freeglut/freeglut/src/mswin/fg_main_mswin.c b/freeglut/freeglut/src/mswin/fg_main_mswin.c index 19daf5a..daa611c 100644 --- a/freeglut/freeglut/src/mswin/fg_main_mswin.c +++ b/freeglut/freeglut/src/mswin/fg_main_mswin.c @@ -518,18 +518,14 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); SetActiveWindow( window->Window.Handle ); - INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); UpdateWindow ( hWnd ); break; case WM_KILLFOCUS: { - 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); /* Check if there are any open menus that need to be closed */ fgPlatformCheckMenuDeactivate(); @@ -553,11 +549,39 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case WM_SETCURSOR: /* printf ( "Cursor event %x %x %x %x\n", window, window->State.Cursor, lParam, wParam ) ; */ if( LOWORD( lParam ) == HTCLIENT ) - fgSetCursor ( window, window->State.Cursor ) ; + { + if (!window->State.pWState.MouseTracking) + { + TRACKMOUSEEVENT tme; + + /* Cursor just entered window, set cursor look, invoke callback and start tracking so that we get a WM_MOUSELEAVE message */ + fgSetCursor ( window, window->State.Cursor ) ; + INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); + + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = window->Window.Handle; + TrackMouseEvent(&tme); + + window->State.pWState.MouseTracking = GL_TRUE; + } + } else + /* Only pass non-client WM_SETCURSOR to DefWindowProc, or we get WM_SETCURSOR on parents of children as well */ lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); break; + case WM_MOUSELEAVE: + { + SFG_Window* saved_window = fgStructure.CurrentWindow; + INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); + fgSetWindow(saved_window); + + window->State.pWState.MouseTracking = GL_FALSE; + lRet = 0; /* As per docs, must return zero */ + } + break; + case WM_SHOWWINDOW: window->State.Visible = GL_TRUE; window->State.Redisplay = GL_TRUE; @@ -828,8 +852,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR case WM_CAPTURECHANGED: /* User has finished resizing the window, force a redraw */ INVOKE_WCB( *window, Display, ( ) ); - - /*lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); */ + lRet = 0; /* Per docs, should return zero */ break; /* Other messages that I have seen and which are not handled already */