X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_window_mswin.c;h=ea2dc156b54f5b7fccc19c8342caafa3f246db38;hb=a5b0c9c64f5c4a35b82af7156f90bbae59d9c405;hp=7720929364c1c551ba2272f4939aa06c15a8f1b0;hpb=637e1260edb9068591665330c32407549ca36535;p=freeglut diff --git a/src/mswin/fg_window_mswin.c b/src/mswin/fg_window_mswin.c index 7720929..ea2dc15 100644 --- a/src/mswin/fg_window_mswin.c +++ b/src/mswin/fg_window_mswin.c @@ -371,6 +371,20 @@ void fgPlatformSetWindow ( SFG_Window *window ) } +void fghGetDefaultWindowStyle(DWORD *flags) +{ + if ( fgState.DisplayMode & GLUT_BORDERLESS ) + { + /* no window decorations needed, no-op */ + } + else if ( fgState.DisplayMode & GLUT_CAPTIONLESS ) + /* only window decoration is a border, no title bar or buttons */ + (*flags) |= WS_DLGFRAME; + else + /* window decoration are a border, title bar and buttons. */ + (*flags) |= WS_OVERLAPPEDWINDOW; +} + /* Get window style and extended window style of a FreeGLUT window * If the window pointer or the window handle is NULL, a fully * decorated window (caption and border) is assumed. @@ -384,8 +398,9 @@ void fghGetStyleFromWindow( const SFG_Window *window, DWORD *windowStyle, DWORD } else { + *windowStyle = 0; + fghGetDefaultWindowStyle(windowStyle); /* WindowExStyle==0 is fine/default, exStyle is currently only used for menu windows */ - *windowStyle = WS_OVERLAPPEDWINDOW; *windowExStyle = 0; } } @@ -601,23 +616,9 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, #if defined(_WIN32_WCE) /* no decorations for windows CE */ #else - /* if this is not a subwindow (child), set its style based on the requested display mode */ + /* if this is not a subwindow (child), set its style based on the requested window decorations */ else if( window->Parent == NULL ) - if ( fgState.DisplayMode & GLUT_BORDERLESS ) - { - /* no window decorations needed */ - } - else if ( fgState.DisplayMode & GLUT_CAPTIONLESS ) - /* only window decoration is a border, no title bar or buttons */ - flags |= WS_DLGFRAME; - else - /* window decoration are a border, title bar and buttons. - * NB: we later query whether the window has a title bar or - * not by testing for the maximize button, as the test for - * WS_CAPTION can be true without the window having a title - * bar. This style WS_OVERLAPPEDWINDOW gives you a maximize - * button. */ - flags |= WS_OVERLAPPEDWINDOW; + fghGetDefaultWindowStyle(&flags); #endif else /* subwindows always have no decoration, but are marked as a child window to the OS */ @@ -750,7 +751,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, ShowWindow( window->Window.Handle, SW_SHOW ); #else ShowWindow( window->Window.Handle, - fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOW ); + fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOWNORMAL ); #endif /* defined(_WIN32_WCE) */ UpdateWindow( window->Window.Handle ); @@ -758,6 +759,74 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, } +void fgPlatformDisplayWindow ( SFG_Window *window ) +{ + RedrawWindow( + window->Window.Handle, NULL, NULL, + RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW + ); +} + + +void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height ) +{ + RECT windowRect; + + /* + * For windowed mode, get the current position of the + * window and resize taking the size of the frame + * decorations into account. + * + * 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. + */ + + /* "GetWindowRect" returns the pixel coordinates of the outside of the window */ + GetWindowRect( window->Window.Handle, &windowRect ); + + /* Create rect in FreeGLUT format, (X,Y) topleft outside window, WxH of client area */ + windowRect.right = windowRect.left+width; + windowRect.bottom = windowRect.top+height; + + if (window->Parent == NULL) + /* get the window rect from this to feed to SetWindowPos, correct for window decorations */ + fghComputeWindowRectFromClientArea_QueryWindow(&windowRect,window,TRUE); + else + { + /* correct rect for position client area of parent window + * (SetWindowPos input for child windows is in coordinates + * relative to the parent's client area). + * Child windows don't have decoration, so no need to correct + * for them. + */ + RECT parentRect; + fghGetClientArea( &parentRect, window->Parent, FALSE ); + OffsetRect(&windowRect,-parentRect.left,-parentRect.top); + } + + /* Do the actual resizing */ + SetWindowPos( window->Window.Handle, + HWND_TOP, + windowRect.left, windowRect.top, + windowRect.right - windowRect.left, + windowRect.bottom- windowRect.top, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING | + SWP_NOZORDER + ); + + /* Set new width and height so we can test for that in WM_SIZE message handler and don't do anything if not needed */ + window->State.Width = width; + window->State.Height = height; +} + + /* * Closes a window, destroying the frame and OpenGL context */ @@ -911,7 +980,6 @@ void fgPlatformGlutFullScreen( SFG_Window *win ) { #if(WINVER >= 0x0500) /* Windows 2000 or later */ - DWORD s; RECT rect; HMONITOR hMonitor; MONITORINFO mi; @@ -923,17 +991,25 @@ void fgPlatformGlutFullScreen( SFG_Window *win ) */ - /* store current window rect */ - GetWindowRect( win->Window.Handle, &win->State.pWState.OldRect ); + /* save current window rect, style, exstyle and maximized state */ + win->State.pWState.OldMaximized = !!IsZoomed(win->Window.Handle); + if (win->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(win->Window.Handle, WM_SYSCOMMAND, SC_RESTORE, 0); - /* store current window style */ - win->State.pWState.OldStyle = s = GetWindowLong(win->Window.Handle, GWL_STYLE); + GetWindowRect( win->Window.Handle, &win->State.pWState.OldRect ); + win->State.pWState.OldStyle = GetWindowLong(win->Window.Handle, GWL_STYLE); + win->State.pWState.OldStyleEx = GetWindowLong(win->Window.Handle, GWL_EXSTYLE); - /* remove decorations from style and add popup style*/ - s &= ~WS_OVERLAPPEDWINDOW; - s |= WS_POPUP; - SetWindowLong(win->Window.Handle, GWL_STYLE, s); - SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + /* remove decorations from style */ + SetWindowLong(win->Window.Handle, GWL_STYLE, + win->State.pWState.OldStyle & ~(WS_CAPTION | WS_THICKFRAME)); + SetWindowLong(win->Window.Handle, GWL_EXSTYLE, + win->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. @@ -995,7 +1071,7 @@ void fgPlatformGlutLeaveFullScreen( SFG_Window *win ) /* restore style of window before making it fullscreen */ SetWindowLong(win->Window.Handle, GWL_STYLE, win->State.pWState.OldStyle); - SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + SetWindowLong(win->Window.Handle, GWL_EXSTYLE, win->State.pWState.OldStyleEx); /* Then resize */ SetWindowPos(win->Window.Handle, @@ -1008,6 +1084,9 @@ void fgPlatformGlutLeaveFullScreen( SFG_Window *win ) SWP_NOZORDER ); + if (win->State.pWState.OldMaximized) + SendMessage(win->Window.Handle, WM_SYSCOMMAND, SC_MAXIMIZE, 0); + win->State.IsFullscreen = GL_FALSE; #endif }