X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_main_mswin.c;h=09e397fe01dab82602bdd815b25c10498d2b1db6;hb=f772f5aa7706c09712d416702b5432803d4f31a8;hp=f1c6eb7bcf21a91052b5349768fe8244b1773cc4;hpb=17ea48c4626b0b2846df89b44b51b14db6371e41;p=freeglut diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index f1c6eb7..09e397f 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -39,7 +39,7 @@ extern void fgNewWGLCreateContext( SFG_Window* window ); extern GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly, unsigned char layer_type ); -extern void fgPlatformCheckMenuDeactivate(); +extern void fgPlatformCheckMenuDeactivate(HWND newFocusWnd); #ifdef WM_TOUCH typedef BOOL (WINAPI *pGetTouchInputInfo)(HTOUCHINPUT,UINT,PTOUCHINPUT,int); @@ -578,6 +578,18 @@ static int fgPlatformGetModifiers (void) ( GetKeyState( VK_RMENU ) < 0 )) ? GLUT_ACTIVE_ALT : 0 ); } +/* Check whether a button (VK_*BUTTON) is currently depressed. Returns + * non-zero (not necessarily 1) if yes. */ +static SHORT fgGetAsyncKeyState(int vKey) +{ + /* MSDN says: "If the most significant bit is set, the key is down, and if + * the least significant bit is set, the key was pressed after the previous + * call to GetAsyncKeyState." This behavior cannot be relied upon however. + * Remove this bit so that we can simply test with ! if key is up. + */ + return GetAsyncKeyState(vKey) & ~1; +} + static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean keydown, WPARAM wParam, LPARAM lParam) { static unsigned char lControl = 0, lShift = 0, lAlt = 0, @@ -629,12 +641,12 @@ static LRESULT fghWindowProcKeyPress(SFG_Window *window, UINT uMsg, GLboolean ke * so when we get an alt, shift or control keypress here, we manually check whether it was the left or the right */ #define ASYNC_KEY_EVENT(winKey,glutKey,keyStateVar)\ - if (!keyStateVar && GetAsyncKeyState ( winKey ))\ + if (!keyStateVar && fgGetAsyncKeyState ( winKey ))\ {\ keypress = glutKey;\ keyStateVar = 1;\ }\ - else if (keyStateVar && !GetAsyncKeyState ( winKey ))\ + else if (keyStateVar && !fgGetAsyncKeyState ( winKey ))\ {\ keypress = glutKey;\ keyStateVar = 0;\ @@ -893,9 +905,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR * force redisplay so display keeps running during dragging. * Screen still wont update when not moving the cursor though... */ - /* PRECT prect = (PRECT) lParam; */ RECT rect; - /* printf("WM_SIZING: nc-area: %i,%i\n",prect->right-prect->left,prect->bottom-prect->top); */ + /* PRECT prect = (PRECT) lParam; + printf("WM_SIZING: nc-area: %i,%i\n",prect->right-prect->left,prect->bottom-prect->top); */ /* Get client area, the rect in lParam is including non-client area. */ fghGetClientArea(&rect,window,FALSE); @@ -969,20 +981,34 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Check if there are any open menus that need to be closed */ - fgPlatformCheckMenuDeactivate(); + fgPlatformCheckMenuDeactivate((HWND)wParam); break; case WM_MOUSEACTIVATE: /* Clicks should not activate the menu. * Especially important when clicking on a menu's submenu item which has no effect. */ - printf("WM_MOUSEACTIVATE\n"); + /*printf("WM_MOUSEACTIVATE\n");*/ if (window->IsMenu) lRet = MA_NOACTIVATEANDEAT; else lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); break; + case WM_NCLBUTTONDOWN: + case WM_NCMBUTTONDOWN: + case WM_NCRBUTTONDOWN: + { + SFG_Menu *menu; + if (fgState.ActiveMenus && (menu = fgGetActiveMenu())) + /* user clicked non-client area of window while a menu is open. Close menu */ + fgDeactivateMenu(menu->ParentWindow); + + /* and always pass to DefWindowProc */ + lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); + } + break; + #if 0 case WM_ACTIVATE: /* printf("WM_ACTIVATE: %x (ID: %i) %d %d\n",lParam, window->ID, HIWORD(wParam), LOWORD(wParam)); */ @@ -1052,12 +1078,12 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR if (wParam) { fghPlatformOnWindowStatusNotify(window, GL_TRUE, GL_FALSE); - window->State.Redisplay = GL_TRUE; + window->State.WorkMask |= GLUT_DISPLAY_WORK; } else { fghPlatformOnWindowStatusNotify(window, GL_FALSE, GL_FALSE); - window->State.Redisplay = GL_FALSE; + window->State.WorkMask &= ~GLUT_DISPLAY_WORK; } break; @@ -1078,7 +1104,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR BeginPaint( hWnd, &ps ); EndPaint( hWnd, &ps ); - window->State.Redisplay = GL_TRUE; + window->State.WorkMask |= GLUT_DISPLAY_WORK; } lRet = 0; /* As per docs, should return 0 */ } @@ -1223,7 +1249,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR SetCapture ( window->Window.Handle ) ; setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */ } - else if (!GetAsyncKeyState(VK_LBUTTON) && !GetAsyncKeyState(VK_MBUTTON) && !GetAsyncKeyState(VK_RBUTTON)) + else if (!fgGetAsyncKeyState(VK_LBUTTON) && !fgGetAsyncKeyState(VK_MBUTTON) && !fgGetAsyncKeyState(VK_RBUTTON)) /* Make sure all mouse buttons are released before releasing capture */ ReleaseCapture () ; @@ -1370,7 +1396,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR #if !defined(_WIN32_WCE) case WM_SYNCPAINT: /* 0x0088 */ /* Another window has moved, need to update this one */ - window->State.Redisplay = GL_TRUE; + window->State.WorkMask |= GLUT_DISPLAY_WORK; lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); /* Help screen says this message must be passed to "DefWindowProc" */ break; @@ -1527,239 +1553,218 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR } -/* Step through the work list */ -void fgPlatformProcessWork(SFG_Window *window) +/* deal with work list items */ +void fgPlatformInitWork(SFG_Window* window) { - unsigned int workMask = window->State.WorkMask; - /* Now clear it so that any callback generated by the actions below can set work again */ - window->State.WorkMask = 0; + RECT windowRect; - /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc - * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when - * they are opened, and work is done before displaying in the mainloop. - */ - if (workMask & GLUT_INIT_WORK) - { - RECT windowRect; - - /* Notify windowStatus/visibility */ - fghPlatformOnWindowStatusNotify(window, window->State.Visible, GL_TRUE); - - /* get and notify window's position */ - GetWindowRect(window->Window.Handle,&windowRect); - fghOnPositionNotify(window, windowRect.left, windowRect.top, GL_TRUE); + /* Notify windowStatus/visibility */ + fghPlatformOnWindowStatusNotify(window, window->State.Visible, GL_TRUE); - /* get and notify window's size */ - GetClientRect(window->Window.Handle,&windowRect); - fghOnReshapeNotify(window, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, GL_TRUE); + /* get and notify window's position */ + GetWindowRect(window->Window.Handle,&windowRect); + fghOnPositionNotify(window, windowRect.left, windowRect.top, GL_TRUE); - /* Call init context callback */ - INVOKE_WCB( *window, InitContext, ()); + /* get and notify window's size */ + GetClientRect(window->Window.Handle,&windowRect); + fghOnReshapeNotify(window, windowRect.right-windowRect.left, windowRect.bottom-windowRect.top, GL_TRUE); +} - /* Lastly, check if we have a display callback, error out if not - * This is the right place to do it, as the redisplay will be - * next right after we exit this function, so there is no more - * opportunity for the user to register a callback for this window. - */ - if (!FETCH_WCB(*window, Display)) - fgError ( "ERROR: No display callback registered for window %d\n", window->ID ); - } +/* On windows we can position, resize and change z order at the same time */ +void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask) +{ + UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER; + HWND insertAfter = HWND_TOP; + RECT clientRect; - /* On windows we can position, resize and change z order at the same time */ - if (workMask & (GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK|GLUT_FULL_SCREEN_WORK)) +#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */ + if (workMask & GLUT_FULL_SCREEN_WORK) { - UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER; - HWND insertAfter = HWND_TOP; - RECT clientRect; + /* This asks us to toggle fullscreen mode */ + flags |= SWP_FRAMECHANGED; -#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */ - if (workMask & GLUT_FULL_SCREEN_WORK) + if (window->State.IsFullscreen) { - /* This asks us to toggle fullscreen mode */ - flags |= SWP_FRAMECHANGED; + /* If we are fullscreen, resize the current window back to its original size */ + /* printf("OldRect %i,%i to %i,%i\n",window->State.pWState.OldRect.left,window->State.pWState.OldRect.top,window->State.pWState.OldRect.right,window->State.pWState.OldRect.bottom); */ - if (window->State.IsFullscreen) - { - /* If we are fullscreen, resize the current window back to its original size */ - /* printf("OldRect %i,%i to %i,%i\n",window->State.pWState.OldRect.left,window->State.pWState.OldRect.top,window->State.pWState.OldRect.right,window->State.pWState.OldRect.bottom); */ + /* restore style of window before making it fullscreen */ + SetWindowLong(window->Window.Handle, GWL_STYLE, window->State.pWState.OldStyle); + SetWindowLong(window->Window.Handle, GWL_EXSTYLE, window->State.pWState.OldStyleEx); - /* restore style of window before making it fullscreen */ - SetWindowLong(window->Window.Handle, GWL_STYLE, window->State.pWState.OldStyle); - SetWindowLong(window->Window.Handle, GWL_EXSTYLE, window->State.pWState.OldStyleEx); - - /* Then set up resize/reposition, unless user already queued up reshape/position work */ - if (!(workMask & GLUT_POSITION_WORK)) - { - workMask |= GLUT_POSITION_WORK; - window->State.DesiredXpos = window->State.pWState.OldRect.left; - window->State.DesiredYpos = window->State.pWState.OldRect.top; - } - if (!(workMask & GLUT_SIZE_WORK)) - { - workMask |= GLUT_SIZE_WORK; - window->State.DesiredWidth = window->State.pWState.OldRect.right - window->State.pWState.OldRect.left; - window->State.DesiredHeight = window->State.pWState.OldRect.bottom - window->State.pWState.OldRect.top; - } - - /* We'll finish off the fullscreen operation below after the other GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK */ + /* Then set up resize/reposition, unless user already queued up reshape/position work */ + if (!(workMask & GLUT_POSITION_WORK)) + { + workMask |= GLUT_POSITION_WORK; + window->State.DesiredXpos = window->State.pWState.OldRect.left; + window->State.DesiredYpos = window->State.pWState.OldRect.top; } - else + if (!(workMask & GLUT_SIZE_WORK)) { - /* we are currently not fullscreen, go to fullscreen: - * remove window decoration and then maximize - */ - RECT rect; - HMONITOR hMonitor; - MONITORINFO mi; - - /* save current window rect, style, exstyle and maximized state */ - window->State.pWState.OldMaximized = !!IsZoomed(window->Window.Handle); - if (window->State.pWState.OldMaximized) - /* We force the window into restored mode before going - * fullscreen because Windows doesn't seem to hide the - * taskbar if the window is in the maximized state. - */ - SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); - - fghGetClientArea( &window->State.pWState.OldRect, window, GL_TRUE ); - window->State.pWState.OldStyle = GetWindowLong(window->Window.Handle, GWL_STYLE); - window->State.pWState.OldStyleEx = GetWindowLong(window->Window.Handle, GWL_EXSTYLE); - - /* remove decorations from style */ - SetWindowLong(window->Window.Handle, GWL_STYLE, - window->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME)); - SetWindowLong(window->Window.Handle, GWL_EXSTYLE, - window->State.pWState.OldStyleEx & ~(WS_EX_DLGMODALFRAME | - WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); - - /* For fullscreen mode, find the monitor that is covered the most - * by the window and get its rect as the resize target. - */ - GetWindowRect(window->Window.Handle, &rect); - hMonitor= MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST); - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - rect = mi.rcMonitor; - - /* then setup window resize, overwriting other work queued on the window */ - window->State.WorkMask |= GLUT_POSITION_WORK | GLUT_SIZE_WORK; - window->State.WorkMask &= ~GLUT_ZORDER_WORK; - window->State.DesiredXpos = rect.left; - window->State.DesiredYpos = rect.top; - window->State.DesiredWidth = rect.right - rect.left; - window->State.DesiredHeight = rect.bottom - rect.top; + workMask |= GLUT_SIZE_WORK; + window->State.DesiredWidth = window->State.pWState.OldRect.right - window->State.pWState.OldRect.left; + window->State.DesiredHeight = window->State.pWState.OldRect.bottom - window->State.pWState.OldRect.top; } + + /* We'll finish off the fullscreen operation below after the other GLUT_POSITION_WORK|GLUT_SIZE_WORK|GLUT_ZORDER_WORK */ + } + else + { + /* we are currently not fullscreen, go to fullscreen: + * remove window decoration and then maximize + */ + RECT rect; + HMONITOR hMonitor; + MONITORINFO mi; + + /* save current window rect, style, exstyle and maximized state */ + window->State.pWState.OldMaximized = !!IsZoomed(window->Window.Handle); + if (window->State.pWState.OldMaximized) + /* We force the window into restored mode before going + * fullscreen because Windows doesn't seem to hide the + * taskbar if the window is in the maximized state. + */ + SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); + + fghGetClientArea( &window->State.pWState.OldRect, window, GL_TRUE ); + window->State.pWState.OldStyle = GetWindowLong(window->Window.Handle, GWL_STYLE); + window->State.pWState.OldStyleEx = GetWindowLong(window->Window.Handle, GWL_EXSTYLE); + + /* remove decorations from style */ + SetWindowLong(window->Window.Handle, GWL_STYLE, + window->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME)); + SetWindowLong(window->Window.Handle, GWL_EXSTYLE, + window->State.pWState.OldStyleEx & ~(WS_EX_DLGMODALFRAME | + WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); + + /* For fullscreen mode, find the monitor that is covered the most + * by the window and get its rect as the resize target. + */ + GetWindowRect(window->Window.Handle, &rect); + hMonitor= MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST); + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + rect = mi.rcMonitor; + + /* then setup window resize, overwriting other work queued on the window */ + window->State.WorkMask |= GLUT_POSITION_WORK | GLUT_SIZE_WORK; + window->State.WorkMask &= ~GLUT_ZORDER_WORK; + window->State.DesiredXpos = rect.left; + window->State.DesiredYpos = rect.top; + window->State.DesiredWidth = rect.right - rect.left; + window->State.DesiredHeight = rect.bottom - rect.top; } + } #endif /*!defined(_WIN32_WCE) */ - /* Now deal with normal position, reshape and z order requests (some might have been set when handling GLUT_FULLSCREEN_WORK above */ + /* Now deal with normal position, reshape and z order requests (some might have been set when handling GLUT_FULLSCREEN_WORK above */ + { + /* get rect describing window's current position and size, + * in screen coordinates and in FreeGLUT format + * (size (right-left, bottom-top) is client area size, top and left + * are outside of window including decorations). + */ + fghGetClientArea( &clientRect, window, TRUE ); + + if (workMask & GLUT_POSITION_WORK) { - /* get rect describing window's current position and size, - * in screen coordinates and in FreeGLUT format - * (size (right-left, bottom-top) is client area size, top and left - * are outside of window including decorations). - */ - fghGetClientArea( &clientRect, window, TRUE ); - - if (workMask & GLUT_POSITION_WORK) - { - flags &= ~SWP_NOMOVE; + flags &= ~SWP_NOMOVE; - /* Move rect so that top-left is at requested position */ - /* This also automatically makes sure that child window requested coordinates are relative - * to top-left of parent's client area (needed input for SetWindowPos on child windows), - * so no need to further correct rect for child windows below (childs don't have decorations either). - */ - OffsetRect(&clientRect,window->State.DesiredXpos-clientRect.left,window->State.DesiredYpos-clientRect.top); - } - if (workMask & GLUT_SIZE_WORK) - { - flags &= ~SWP_NOSIZE; + /* Move rect so that top-left is at requested position */ + /* This also automatically makes sure that child window requested coordinates are relative + * to top-left of parent's client area (needed input for SetWindowPos on child windows), + * so no need to further correct rect for child windows below (childs don't have decorations either). + */ + OffsetRect(&clientRect,window->State.DesiredXpos-clientRect.left,window->State.DesiredYpos-clientRect.top); + } + if (workMask & GLUT_SIZE_WORK) + { + flags &= ~SWP_NOSIZE; - /* Note on maximizing behavior of Windows: the resize borders are off - * the screen such that the client area extends all the way from the - * leftmost corner to the rightmost corner to maximize screen real - * estate. A caption is still shown however to allow interaction with - * the window controls. This is default behavior of Windows that - * FreeGLUT sticks with. To alter, one would have to check if - * WS_MAXIMIZE style is set when a resize event is triggered, and - * then manually correct the windowRect to put the borders back on - * screen. - */ - - /* Set new size of window, WxH specify client area */ - clientRect.right = clientRect.left + window->State.DesiredWidth; - clientRect.bottom = clientRect.top + window->State.DesiredHeight; - } - if (workMask & GLUT_ZORDER_WORK) - { - flags &= ~SWP_NOZORDER; - - /* Could change this to push it down or up one window at a time with some - * more code using GetWindow with GW_HWNDPREV and GW_HWNDNEXT. - * What would be consistent with X11? Win32 GLUT does what we do here... - */ - if (window->State.DesiredZOrder < 0) - insertAfter = HWND_BOTTOM; - } + /* Note on maximizing behavior of Windows: the resize borders are off + * the screen such that the client area extends all the way from the + * leftmost corner to the rightmost corner to maximize screen real + * estate. A caption is still shown however to allow interaction with + * the window controls. This is default behavior of Windows that + * FreeGLUT sticks with. To alter, one would have to check if + * WS_MAXIMIZE style is set when a resize event is triggered, and + * then manually correct the windowRect to put the borders back on + * screen. + */ + + /* Set new size of window, WxH specify client area */ + clientRect.right = clientRect.left + window->State.DesiredWidth; + clientRect.bottom = clientRect.top + window->State.DesiredHeight; } - - /* Adjust for window decorations - * Child windows don't have decoration, so no need to correct - */ - if (!window->Parent) - /* get the window rect from this to feed to SetWindowPos, correct for window decorations */ - fghComputeWindowRectFromClientArea_QueryWindow(&clientRect,window,TRUE); - - /* Do the requested positioning, moving, and z order push/pop. */ - SetWindowPos( window->Window.Handle, - insertAfter, - clientRect.left, clientRect.top, - clientRect.right - clientRect.left, - clientRect.bottom- clientRect.top, - flags - ); - - /* Finish off the fullscreen operation we were doing, if any */ - if (workMask & GLUT_FULL_SCREEN_WORK) + if (workMask & GLUT_ZORDER_WORK) { - if (window->State.IsFullscreen) - { - /* leaving fullscreen, restore maximized state, if any */ - if (window->State.pWState.OldMaximized) - SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0); - - window->State.IsFullscreen = GL_FALSE; - } - else - window->State.IsFullscreen = GL_TRUE; + flags &= ~SWP_NOZORDER; + + /* Could change this to push it down or up one window at a time with some + * more code using GetWindow with GW_HWNDPREV and GW_HWNDNEXT. + * What would be consistent with X11? Win32 GLUT does what we do here... + */ + if (window->State.DesiredZOrder < 0) + insertAfter = HWND_BOTTOM; } } - if (workMask & GLUT_VISIBILITY_WORK) + /* Adjust for window decorations + * Child windows don't have decoration, so no need to correct + */ + if (!window->Parent) + /* get the window rect from this to feed to SetWindowPos, correct for window decorations */ + fghComputeWindowRectFromClientArea_QueryWindow(&clientRect,window,TRUE); + + /* Do the requested positioning, moving, and z order push/pop. */ + SetWindowPos( window->Window.Handle, + insertAfter, + clientRect.left, clientRect.top, + clientRect.right - clientRect.left, + clientRect.bottom- clientRect.top, + flags + ); + + /* Finish off the fullscreen operation we were doing, if any */ + if (workMask & GLUT_FULL_SCREEN_WORK) { - /* Visibility status of window gets updated in the WM_SHOWWINDOW and WM_SIZE handlers */ - int cmdShow = 0; - SFG_Window *win = window; - switch (window->State.DesiredVisibility) + if (window->State.IsFullscreen) { - case DesireHiddenState: - cmdShow = SW_HIDE; - break; - case DesireIconicState: - cmdShow = SW_MINIMIZE; - /* Call on top-level window */ - while (win->Parent) - win = win->Parent; - break; - case DesireNormalState: - if (win->IsMenu) - cmdShow = SW_SHOWNOACTIVATE; /* Just show, don't activate if its a menu */ - else - cmdShow = SW_SHOW; - break; + /* leaving fullscreen, restore maximized state, if any */ + if (window->State.pWState.OldMaximized) + SendMessage(window->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + + window->State.IsFullscreen = GL_FALSE; } + else + window->State.IsFullscreen = GL_TRUE; + } +} + - ShowWindow( win->Window.Handle, cmdShow ); +void fgPlatformVisibilityWork(SFG_Window* window) +{ + /* Visibility status of window gets updated in the WM_SHOWWINDOW and WM_SIZE handlers */ + int cmdShow = 0; + SFG_Window *win = window; + switch (window->State.DesiredVisibility) + { + case DesireHiddenState: + cmdShow = SW_HIDE; + break; + case DesireIconicState: + cmdShow = SW_MINIMIZE; + /* Call on top-level window */ + while (win->Parent) + win = win->Parent; + break; + case DesireNormalState: + if (win->IsMenu && (!fgStructure.GameModeWindow || win->ActiveMenu->ParentWindow != fgStructure.GameModeWindow)) + cmdShow = SW_SHOWNA; /* Just show, don't activate window if its a menu. Only exception is when the parent is a gamemode window as the menu would pop under it when we do this... */ + else + cmdShow = SW_SHOW; + break; } + + ShowWindow( win->Window.Handle, cmdShow ); } \ No newline at end of file