* API.cs: added MonitorFromWindow/MonitorFromPoint methods.

* WinGLNative.cs: fixed handling of WindowState.Maximized when WindowBorder is Hidden.
    WindowStateChanged events are now correctly raised on all state changes.
This commit is contained in:
the_fiddler 2009-10-18 09:42:41 +00:00
parent c5464bc5d0
commit 6be563211f
2 changed files with 79 additions and 22 deletions

View file

@ -60,6 +60,7 @@ namespace OpenTK.Platform.Windows
using LPDEVMODE = DeviceMode; using LPDEVMODE = DeviceMode;
using HRESULT = System.IntPtr; using HRESULT = System.IntPtr;
using HMONITOR = System.IntPtr;
using DWORD_PTR = System.IntPtr; using DWORD_PTR = System.IntPtr;
using UINT_PTR = System.UIntPtr; using UINT_PTR = System.UIntPtr;
@ -894,6 +895,20 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region MonitorFromPoint
[DllImport("user32.dll", SetLastError = true)]
public static extern HMONITOR MonitorFromPoint(POINT pt, MonitorFrom dwFlags);
#endregion
#region MonitorFromWindow
[DllImport("user32.dll", SetLastError = true)]
public static extern HMONITOR MonitorFromWindow(HWND hwnd, MonitorFrom dwFlags);
#endregion
#endregion #endregion
#region Input functions #region Input functions
@ -4013,6 +4028,17 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region MonitorFrom
enum MonitorFrom
{
Null = 0,
Primary = 1,
Nearest = 2,
}
#endregion
#endregion #endregion
#region --- Callbacks --- #region --- Callbacks ---

View file

@ -62,6 +62,7 @@ namespace OpenTK.Platform.Windows
WinWindowInfo window, child_window; WinWindowInfo window, child_window;
WindowBorder windowBorder = WindowBorder.Resizable, previous_window_border; WindowBorder windowBorder = WindowBorder.Resizable, previous_window_border;
WindowState windowState = WindowState.Normal; WindowState windowState = WindowState.Normal;
bool borderless_maximized_window_state = false;
System.Drawing.Rectangle System.Drawing.Rectangle
bounds = new System.Drawing.Rectangle(), bounds = new System.Drawing.Rectangle(),
@ -243,15 +244,24 @@ namespace OpenTK.Platform.Windows
case WindowMessage.SIZE: case WindowMessage.SIZE:
SizeMessage state = (SizeMessage)wParam.ToInt64(); SizeMessage state = (SizeMessage)wParam.ToInt64();
WindowState new_state = windowState;
switch (state) switch (state)
{ {
case SizeMessage.RESTORED: windowState = WindowState.Normal; break; case SizeMessage.RESTORED: new_state = borderless_maximized_window_state ?
case SizeMessage.MINIMIZED: windowState = WindowState.Minimized; break; WindowState.Maximized : WindowState.Normal; break;
case SizeMessage.MAXIMIZED: case SizeMessage.MINIMIZED: new_state = WindowState.Minimized; break;
windowState = WindowBorder == WindowBorder.Hidden ? WindowState.Fullscreen : WindowState.Maximized; case SizeMessage.MAXIMIZED: new_state = WindowBorder == WindowBorder.Hidden ?
WindowState.Fullscreen : WindowState.Maximized;
break; break;
} }
if (new_state != windowState)
{
windowState = new_state;
if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty);
}
break; break;
#endregion #endregion
@ -846,19 +856,43 @@ namespace OpenTK.Platform.Windows
return; return;
ShowWindowCommand command = 0; ShowWindowCommand command = 0;
borderless_maximized_window_state = false;
switch (value) switch (value)
{ {
case WindowState.Normal: case WindowState.Normal:
command = ShowWindowCommand.RESTORE; command = ShowWindowCommand.RESTORE;
if (WindowBorder == WindowBorder.Hidden && previous_window_border != WindowBorder.Hidden)
// If we are leaving fullscreen mode, restore previous border.
if (WindowState == WindowState.Fullscreen)
{
WindowBorder = previous_window_border; WindowBorder = previous_window_border;
}
break; break;
case WindowState.Maximized: case WindowState.Maximized:
// Note: if we use the MAXIMIZE command and the window border is Hidden (i.e. WS_POPUP),
// we will enter fullscreen mode - we don't want that! As a workaround, we'll resize the window
// manually to cover the whole working area of the current monitor.
// Reset state to avoid strange interactions with fullscreen/minimized windows.
WindowState = WindowState.Normal;
if (WindowBorder == WindowBorder.Hidden)
{
IntPtr current_monitor = Functions.MonitorFromWindow(window.WindowHandle, MonitorFrom.Nearest);
MonitorInfo info = new MonitorInfo();
info.Size = MonitorInfo.SizeInBytes;
Functions.GetMonitorInfo(current_monitor, ref info);
previous_bounds = Bounds;
borderless_maximized_window_state = true;
Bounds = info.Work.ToRectangle();
}
else
{
command = ShowWindowCommand.MAXIMIZE; command = ShowWindowCommand.MAXIMIZE;
if (WindowBorder == WindowBorder.Hidden && previous_window_border != WindowBorder.Hidden) }
WindowBorder = previous_window_border;
break; break;
case WindowState.Minimized: case WindowState.Minimized:
@ -866,29 +900,26 @@ namespace OpenTK.Platform.Windows
break; break;
case WindowState.Fullscreen: case WindowState.Fullscreen:
// We achieve fullscreen by hiding the window border and maximizing the window. // We achieve fullscreen by hiding the window border and sending the MAXIMIZE command.
// We have to 'trick' maximize above to not restore the border, by making it think // We cannot use the WindowState.Maximized directly, as that will not send the MAXIMIZE
// previous_window_border == Hidden. // command for windows with hidden borders.
// After the trick, we store the 'real' previous border, to allow state changes to work
// as expected. // Reset state to avoid strange side-effects from maximized/minimized windows.
WindowState = WindowState.Normal;
previous_bounds = Bounds; previous_bounds = Bounds;
WindowBorder temp = WindowBorder; previous_window_border = WindowBorder;
previous_window_border = WindowBorder.Hidden;
WindowBorder = WindowBorder.Hidden; WindowBorder = WindowBorder.Hidden;
WindowState = WindowState.Maximized; command = ShowWindowCommand.MAXIMIZE;
previous_window_border = temp;
break; break;
} }
if (WindowStateChanged != null)
WindowStateChanged(this, EventArgs.Empty);
if (command != 0) if (command != 0)
Functions.ShowWindow(window.WindowHandle, command); Functions.ShowWindow(window.WindowHandle, command);
// Restore previous window size when leaving fullscreen mode // Restore previous window size when leaving fullscreen mode
if (command == ShowWindowCommand.RESTORE && if (command == ShowWindowCommand.RESTORE && previous_bounds != System.Drawing.Rectangle.Empty)
previous_bounds != System.Drawing.Rectangle.Empty)
{ {
Bounds = previous_bounds; Bounds = previous_bounds;
previous_bounds = System.Drawing.Rectangle.Empty; previous_bounds = System.Drawing.Rectangle.Empty;