2007-07-23 00:15:18 +00:00
|
|
|
|
#region --- License ---
|
|
|
|
|
/* Copyright (c) 2007 Stefanos Apostolopoulos
|
|
|
|
|
* See license.txt for license info
|
|
|
|
|
*/
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region --- Using directives ---
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Windows.Forms;
|
2007-08-04 12:09:58 +00:00
|
|
|
|
using System.Diagnostics;
|
2008-02-02 00:58:26 +00:00
|
|
|
|
using OpenTK.Graphics.OpenGL;
|
2007-09-26 11:55:55 +00:00
|
|
|
|
using OpenTK.Input;
|
2008-01-31 13:15:17 +00:00
|
|
|
|
using OpenTK.Graphics;
|
2008-04-20 17:54:16 +00:00
|
|
|
|
using System.Drawing;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
namespace OpenTK.Platform.Windows
|
|
|
|
|
{
|
2007-08-05 13:42:31 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Drives GameWindow on Windows.
|
|
|
|
|
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
|
|
|
|
/// </summary>
|
2008-01-11 20:24:20 +00:00
|
|
|
|
internal sealed class WinGLNative : System.Windows.Forms.NativeWindow, INativeGLWindow
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2007-08-04 12:09:58 +00:00
|
|
|
|
#region --- Fields ---
|
|
|
|
|
|
2008-01-06 02:25:56 +00:00
|
|
|
|
private IInputDriver driver;
|
2007-08-05 13:42:31 +00:00
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
private bool visible = true;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
private bool disposed;
|
2007-08-10 16:55:24 +00:00
|
|
|
|
private bool isExiting;
|
2007-08-06 09:22:04 +00:00
|
|
|
|
private bool exists;
|
2008-02-28 13:57:07 +00:00
|
|
|
|
private WinWindowInfo window;
|
2008-04-20 17:54:16 +00:00
|
|
|
|
private WindowBorder windowBorder = WindowBorder.Resizable, previous_window_border;
|
|
|
|
|
private WindowState windowState = WindowState.Normal;
|
|
|
|
|
|
2007-08-21 12:04:01 +00:00
|
|
|
|
private int top, bottom, left, right;
|
2008-01-23 13:26:14 +00:00
|
|
|
|
private int width = 0, height = 0;
|
2008-04-20 17:54:16 +00:00
|
|
|
|
private Rectangle previous_client_area;
|
|
|
|
|
|
|
|
|
|
private Point position = new Point();
|
|
|
|
|
private Rectangle client_rectangle = new Rectangle();
|
|
|
|
|
private Size window_size = new Size();
|
|
|
|
|
private Rectangle borders = new Rectangle();
|
2007-08-06 11:22:18 +00:00
|
|
|
|
|
2007-09-26 11:55:55 +00:00
|
|
|
|
private ResizeEventArgs resizeEventArgs = new ResizeEventArgs();
|
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
/// <summary>
|
2007-09-26 11:55:55 +00:00
|
|
|
|
/// For use in PeekMessage.
|
2007-09-02 00:16:22 +00:00
|
|
|
|
/// </summary>
|
|
|
|
|
private MSG myGoodMsg = new MSG();
|
|
|
|
|
|
2007-08-21 12:04:01 +00:00
|
|
|
|
private int left_border, right_border, top_border, bottom_border;
|
2007-08-04 12:09:58 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
#region --- Contructors ---
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// <internal />
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// <summary>
|
2007-08-05 10:33:23 +00:00
|
|
|
|
/// Constructs a new WinGLNative class. Call CreateWindow to create the
|
|
|
|
|
/// actual render window.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
internal WinGLNative()
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2007-08-05 13:42:31 +00:00
|
|
|
|
Debug.Print("Native window driver: {0}", this.ToString());
|
2007-08-04 12:09:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
#region --- Protected Members ---
|
|
|
|
|
|
2007-08-04 12:09:58 +00:00
|
|
|
|
#region protected override void WndProc(ref Message m)
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Processes incoming WM_* messages.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="m">Reference to the incoming Windows Message.</param>
|
|
|
|
|
protected override void WndProc(ref Message m)
|
|
|
|
|
{
|
2007-09-02 00:16:22 +00:00
|
|
|
|
switch ((WindowMessage)m.Msg)
|
2007-08-04 12:09:58 +00:00
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
case WindowMessage.ACTIVATE:
|
|
|
|
|
break;
|
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
case WindowMessage.WINDOWPOSCHANGED:
|
2008-04-20 17:54:16 +00:00
|
|
|
|
WindowPosition pos = (WindowPosition)Marshal.PtrToStructure(m.LParam, typeof(WindowPosition));
|
|
|
|
|
position.X = pos.x;
|
|
|
|
|
position.Y = pos.y;
|
|
|
|
|
window_size.Width = pos.cx;
|
|
|
|
|
window_size.Height = pos.cy;
|
|
|
|
|
|
|
|
|
|
Functions.GetClientRect(Handle, out client_rectangle);
|
|
|
|
|
|
|
|
|
|
//client_size.Width = pos.cx - (left_border + right_border);
|
|
|
|
|
//client_size.Height = pos.cy - (top_border + bottom_border);
|
|
|
|
|
|
2007-08-04 12:09:58 +00:00
|
|
|
|
// Get window size
|
2008-04-20 17:54:16 +00:00
|
|
|
|
//int _width = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(WindowPosition), "cx"));
|
|
|
|
|
//int _height = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(WindowPosition), "cy"));
|
|
|
|
|
|
|
|
|
|
//if (client_size.Width != new_width || client_size.Height != new_height)
|
|
|
|
|
//{
|
|
|
|
|
// client_size.Width = new_width;
|
|
|
|
|
// client_size.Height = new_height;
|
|
|
|
|
// return;
|
|
|
|
|
//}
|
|
|
|
|
|
2007-08-04 12:09:58 +00:00
|
|
|
|
// If the message was not a resize notification, send it to the default WndProc.
|
|
|
|
|
break;
|
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
//case WindowMessage.MOUSELEAVE:
|
|
|
|
|
// Cursor.Current = Cursors.Default;
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
|
|
//case WindowMessage.MOUSE_ENTER:
|
|
|
|
|
// Cursor.Current = Cursors.Default;
|
|
|
|
|
// break;
|
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
case WindowMessage.CREATE:
|
2007-08-04 12:09:58 +00:00
|
|
|
|
// Set the window width and height:
|
2008-01-23 13:26:14 +00:00
|
|
|
|
width = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(CreateStruct), "cx"));
|
|
|
|
|
height = Marshal.ReadInt32(m.LParam, (int)Marshal.OffsetOf(typeof(CreateStruct), "cy"));
|
|
|
|
|
width -= (left_border + right_border);
|
|
|
|
|
height -= (top_border + bottom_border);
|
2007-08-05 13:42:31 +00:00
|
|
|
|
|
2007-08-04 12:09:58 +00:00
|
|
|
|
// Raise the Create event
|
|
|
|
|
this.OnCreate(EventArgs.Empty);
|
|
|
|
|
return;
|
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
case WindowMessage.CLOSE:
|
2007-11-11 20:23:25 +00:00
|
|
|
|
//this.DestroyWindow();
|
|
|
|
|
this.OnDestroy(EventArgs.Empty);
|
2008-01-15 00:10:56 +00:00
|
|
|
|
return;
|
|
|
|
|
//break;
|
2007-08-05 13:42:31 +00:00
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
case WindowMessage.DESTROY:
|
2007-11-11 20:23:25 +00:00
|
|
|
|
//this.OnDestroy(EventArgs.Empty);
|
|
|
|
|
exists = false;
|
|
|
|
|
isExiting = true;
|
2007-08-06 11:22:18 +00:00
|
|
|
|
break;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
case WindowMessage.QUIT:
|
2007-08-10 16:55:24 +00:00
|
|
|
|
isExiting = true;
|
2007-09-02 00:16:22 +00:00
|
|
|
|
//this.Dispose();
|
2007-08-10 16:55:24 +00:00
|
|
|
|
//Debug.WriteLine("Application quit.");
|
2007-08-04 12:09:58 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
//DefWndProc(ref m);
|
|
|
|
|
base.WndProc(ref m);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-05 13:42:31 +00:00
|
|
|
|
#region --- INativeGLWindow Members ---
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
#region public void ProcessEvents()
|
|
|
|
|
|
2007-08-04 12:09:58 +00:00
|
|
|
|
private int ret;
|
2007-09-02 00:16:22 +00:00
|
|
|
|
MSG msg;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
public void ProcessEvents()
|
|
|
|
|
{
|
2007-08-04 12:09:58 +00:00
|
|
|
|
while (!IsIdle)
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2007-09-26 11:55:55 +00:00
|
|
|
|
ret = Functions.GetMessage(ref msg, Handle, 0, 0);
|
2007-08-04 12:09:58 +00:00
|
|
|
|
if (ret == -1)
|
|
|
|
|
{
|
|
|
|
|
throw new ApplicationException(String.Format(
|
|
|
|
|
"An error happened while processing the message queue. Windows error: {0}",
|
|
|
|
|
Marshal.GetLastWin32Error()));
|
|
|
|
|
}
|
2007-09-26 11:55:55 +00:00
|
|
|
|
Functions.DispatchMessage(ref msg);
|
2007-08-06 11:22:18 +00:00
|
|
|
|
//WndProc(ref msg);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-11-10 18:25:33 +00:00
|
|
|
|
#region public IInputDriver InputDriver
|
|
|
|
|
|
|
|
|
|
public IInputDriver InputDriver
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return driver;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-06 09:22:04 +00:00
|
|
|
|
#region public bool Exists
|
2007-08-04 12:09:58 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Returns true if a render window/context exists.
|
|
|
|
|
/// </summary>
|
2007-08-06 09:22:04 +00:00
|
|
|
|
public bool Exists
|
2007-08-04 12:09:58 +00:00
|
|
|
|
{
|
2007-08-06 09:22:04 +00:00
|
|
|
|
get { return exists; }
|
2007-08-04 12:09:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public bool IsExiting
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2007-08-10 16:55:24 +00:00
|
|
|
|
public bool IsExiting
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2007-08-10 16:55:24 +00:00
|
|
|
|
get { return isExiting; }
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public bool IsIdle
|
|
|
|
|
|
|
|
|
|
public bool IsIdle
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2007-08-04 12:09:58 +00:00
|
|
|
|
//return !API.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
|
2007-09-26 11:55:55 +00:00
|
|
|
|
return !Functions.PeekMessage(ref myGoodMsg, this.Handle, 0, 0, 0);
|
2007-08-04 12:09:58 +00:00
|
|
|
|
//return API.GetQueueStatus(API.QueueStatusFlags.ALLEVENTS) == 0;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-09-26 11:55:55 +00:00
|
|
|
|
#region public string Text
|
|
|
|
|
|
|
|
|
|
public string Title
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
StringBuilder title = new StringBuilder(256);
|
2008-03-03 12:44:56 +00:00
|
|
|
|
Functions.GetWindowText(window.WindowHandle, title, title.Capacity);
|
2007-09-26 11:55:55 +00:00
|
|
|
|
return title.ToString();
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
#if DEBUG
|
2008-03-03 12:44:56 +00:00
|
|
|
|
bool ret = Functions.SetWindowText(window.WindowHandle, value);
|
2007-09-26 11:55:55 +00:00
|
|
|
|
if (ret)
|
2008-03-03 12:44:56 +00:00
|
|
|
|
Debug.Print("Window {0} title changed to {1}.", window.WindowHandle, value);
|
2007-09-26 11:55:55 +00:00
|
|
|
|
else
|
2008-03-03 12:44:56 +00:00
|
|
|
|
Debug.Print("Window {0} title failed to change to {1}.", window.WindowHandle, value);
|
2007-09-26 11:55:55 +00:00
|
|
|
|
#else
|
2008-03-03 12:44:56 +00:00
|
|
|
|
Functions.SetWindowText(window.WindowHandle, value);
|
2007-09-26 11:55:55 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public bool Visible
|
|
|
|
|
|
2007-09-26 15:44:32 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// TODO
|
|
|
|
|
/// </summary>
|
2007-09-26 11:55:55 +00:00
|
|
|
|
public bool Visible
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2008-01-24 12:36:40 +00:00
|
|
|
|
return visible;
|
2007-09-26 11:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
2008-01-24 12:36:40 +00:00
|
|
|
|
if (value && !Visible)
|
|
|
|
|
{
|
|
|
|
|
Functions.ShowWindow(Handle, ShowWindowCommand.SHOWNORMAL);
|
|
|
|
|
visible = true;
|
|
|
|
|
}
|
|
|
|
|
else if (!value && Visible)
|
|
|
|
|
{
|
|
|
|
|
Functions.ShowWindow(Handle, ShowWindowCommand.HIDE);
|
|
|
|
|
visible = false;
|
|
|
|
|
}
|
2007-09-26 11:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-05 13:42:31 +00:00
|
|
|
|
#region public IWindowInfo WindowInfo
|
|
|
|
|
|
|
|
|
|
public IWindowInfo WindowInfo
|
|
|
|
|
{
|
2007-08-06 11:22:18 +00:00
|
|
|
|
get { return window; }
|
2007-09-25 16:45:12 +00:00
|
|
|
|
//private set { window = value as WindowInfo; }
|
2007-08-06 11:22:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-03-01 13:15:31 +00:00
|
|
|
|
#region public void CreateWindow(int width, int height, GraphicsMode mode, out IGraphicsContext context)
|
2007-08-06 11:22:18 +00:00
|
|
|
|
|
2008-03-01 13:15:31 +00:00
|
|
|
|
public void CreateWindow(int width, int height, GraphicsMode mode, out IGraphicsContext context)
|
2007-08-06 11:22:18 +00:00
|
|
|
|
{
|
2008-01-31 13:15:17 +00:00
|
|
|
|
Debug.Print("Creating native window.");
|
2007-08-06 11:22:18 +00:00
|
|
|
|
Debug.Indent();
|
2008-02-28 15:28:40 +00:00
|
|
|
|
//Debug.Print("GraphicsMode: {0}", format.ToString());
|
2007-08-06 11:22:18 +00:00
|
|
|
|
|
|
|
|
|
CreateParams cp = new CreateParams();
|
|
|
|
|
cp.ClassStyle =
|
2007-09-02 00:16:22 +00:00
|
|
|
|
(int)WindowClassStyle.OwnDC |
|
|
|
|
|
(int)WindowClassStyle.VRedraw |
|
|
|
|
|
(int)WindowClassStyle.HRedraw |
|
|
|
|
|
(int)WindowClassStyle.Ime;
|
2007-08-06 11:22:18 +00:00
|
|
|
|
cp.Style =
|
2007-09-02 00:16:22 +00:00
|
|
|
|
(int)WindowStyle.Visible |
|
|
|
|
|
(int)WindowStyle.ClipChildren |
|
|
|
|
|
(int)WindowStyle.ClipSiblings |
|
|
|
|
|
(int)WindowStyle.OverlappedWindow;
|
2007-08-21 12:04:01 +00:00
|
|
|
|
|
2007-09-02 00:16:22 +00:00
|
|
|
|
Rectangle rect = new Rectangle();
|
2007-08-21 12:04:01 +00:00
|
|
|
|
rect.top = rect.left = 0;
|
2008-01-23 14:17:09 +00:00
|
|
|
|
rect.bottom = height;
|
|
|
|
|
rect.right = width;
|
2007-09-26 11:55:55 +00:00
|
|
|
|
Functions.AdjustWindowRect(ref rect, WindowStyle.OverlappedWindow, false);
|
2007-08-21 12:04:01 +00:00
|
|
|
|
|
|
|
|
|
// Not used
|
|
|
|
|
Top = 0;
|
|
|
|
|
Left = 0;
|
2008-01-23 14:17:09 +00:00
|
|
|
|
Right = width;
|
|
|
|
|
Bottom = height;
|
2007-08-21 12:04:01 +00:00
|
|
|
|
// --------
|
|
|
|
|
|
|
|
|
|
top_border = -rect.top;
|
|
|
|
|
left_border = -rect.left;
|
2008-01-23 14:17:09 +00:00
|
|
|
|
bottom_border = rect.bottom - height;
|
|
|
|
|
right_border = rect.right - width;
|
2007-12-09 18:15:51 +00:00
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
//cp.Width = rect.right - rect.left;
|
|
|
|
|
//cp.Height = rect.bottom - rect.top;
|
|
|
|
|
//cp.Caption = "OpenTK Game Window";
|
2008-01-31 13:15:17 +00:00
|
|
|
|
|
2007-08-06 11:22:18 +00:00
|
|
|
|
// Keep in mind that some construction code runs in WM_CREATE,
|
|
|
|
|
// which is raised CreateHandle()
|
|
|
|
|
CreateHandle(cp);
|
|
|
|
|
|
2007-12-09 18:15:51 +00:00
|
|
|
|
if (this.Handle != IntPtr.Zero)
|
2007-08-06 11:22:18 +00:00
|
|
|
|
{
|
2008-01-11 20:24:20 +00:00
|
|
|
|
Debug.WriteLine("Window creation succesful.");
|
|
|
|
|
//context.Info = new OpenTK.Platform.WindowInfo(this);
|
|
|
|
|
//context.CreateContext();
|
|
|
|
|
//Debug.WriteLine("Context creation successful.");
|
2007-08-06 11:22:18 +00:00
|
|
|
|
exists = true;
|
|
|
|
|
}
|
2007-12-09 18:15:51 +00:00
|
|
|
|
else throw new ApplicationException(String.Format(
|
|
|
|
|
"Could not create native window and/or context. Handle: {0}",
|
|
|
|
|
this.Handle));
|
2007-08-06 11:22:18 +00:00
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
Functions.SetWindowPos(this.Handle, WindowPlacementOptions.TOP, Left, Top, rect.right - rect.left,
|
|
|
|
|
rect.bottom - rect.top, SetWindowPosFlags.SHOWWINDOW);
|
2008-01-15 00:02:58 +00:00
|
|
|
|
|
2008-03-01 13:15:31 +00:00
|
|
|
|
context = new GraphicsContext(mode, window);
|
2008-01-15 10:31:03 +00:00
|
|
|
|
|
2007-08-06 11:22:18 +00:00
|
|
|
|
Debug.Unindent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region OnCreate
|
|
|
|
|
|
|
|
|
|
public event CreateEvent Create;
|
|
|
|
|
|
|
|
|
|
public void OnCreate(EventArgs e)
|
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
this.window = new WinWindowInfo(Handle, null);
|
2008-01-11 20:24:20 +00:00
|
|
|
|
|
2008-01-06 02:25:56 +00:00
|
|
|
|
//driver = new WinRawInput(this.window); // Disabled until the mouse issues are resolved.
|
|
|
|
|
driver = new WMInput(this.window);
|
2007-08-06 11:22:18 +00:00
|
|
|
|
|
|
|
|
|
Debug.Print("Window created: {0}", window);
|
|
|
|
|
|
|
|
|
|
if (this.Create != null)
|
|
|
|
|
this.Create(this, e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region private void DestroyWindow()
|
|
|
|
|
|
2007-08-10 16:55:24 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Starts the teardown sequence for the current window.
|
|
|
|
|
/// </summary>
|
2007-08-06 11:22:18 +00:00
|
|
|
|
public void DestroyWindow()
|
|
|
|
|
{
|
|
|
|
|
Debug.Print("Destroying window: {0}", window.ToString());
|
2008-02-28 13:57:07 +00:00
|
|
|
|
//Functions.PostMessage(this.Handle, WindowMessage.DESTROY, IntPtr.Zero, IntPtr.Zero);
|
|
|
|
|
Functions.DestroyWindow(this.Handle);
|
2007-08-06 11:22:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region OnDestroy
|
|
|
|
|
|
|
|
|
|
public void OnDestroy(EventArgs e)
|
|
|
|
|
{
|
2007-11-11 20:23:25 +00:00
|
|
|
|
Debug.Print("Destroy event fired from window: {0}", window.ToString());
|
2007-08-10 16:55:24 +00:00
|
|
|
|
if (this.Destroy != null)
|
|
|
|
|
this.Destroy(this, e);
|
2007-11-11 20:23:25 +00:00
|
|
|
|
/*
|
2007-08-06 11:22:18 +00:00
|
|
|
|
if (this.Handle != IntPtr.Zero)
|
|
|
|
|
{
|
|
|
|
|
Debug.Print("Window handle {0} destroyed.", this.Handle);
|
|
|
|
|
//this.DestroyHandle(); // Destroyed automatically by DefWndProc
|
2007-08-22 00:30:16 +00:00
|
|
|
|
//this.Dispose();
|
2007-08-06 11:22:18 +00:00
|
|
|
|
exists = false;
|
|
|
|
|
}
|
2007-11-11 20:23:25 +00:00
|
|
|
|
*/
|
2007-08-22 00:30:16 +00:00
|
|
|
|
//API.PostQuitMessage(0);
|
2007-08-05 13:42:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-06 11:22:18 +00:00
|
|
|
|
public event DestroyEvent Destroy;
|
|
|
|
|
|
2007-08-05 13:42:31 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2008-01-06 02:25:56 +00:00
|
|
|
|
#region PointToClient
|
|
|
|
|
|
|
|
|
|
public void PointToClient(ref System.Drawing.Point p)
|
|
|
|
|
{
|
|
|
|
|
if (!Functions.ScreenToClient(this.Handle, ref p))
|
|
|
|
|
throw new InvalidOperationException(String.Format(
|
|
|
|
|
"Could not convert point {0} from client to screen coordinates. Windows error: {1}",
|
|
|
|
|
p.ToString(), Marshal.GetLastWin32Error()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region PointToScreen
|
|
|
|
|
|
|
|
|
|
public void PointToScreen(ref System.Drawing.Point p)
|
|
|
|
|
{
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
#region public WindowState WindowState
|
|
|
|
|
|
|
|
|
|
public WindowState WindowState
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return windowState;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
IntPtr style = Functions.GetWindowLong(Handle, GetWindowLongOffsets.STYLE);
|
|
|
|
|
ShowWindowCommand command = (ShowWindowCommand)0;
|
|
|
|
|
SetWindowPosFlags flags = SetWindowPosFlags.NOREPOSITION;
|
|
|
|
|
int new_width = 0, new_height = 0;
|
|
|
|
|
|
|
|
|
|
switch (value)
|
|
|
|
|
{
|
|
|
|
|
case WindowState.Normal:
|
|
|
|
|
command = ShowWindowCommand.RESTORE;
|
|
|
|
|
flags |= SetWindowPosFlags.SHOWWINDOW | SetWindowPosFlags.FRAMECHANGED;
|
|
|
|
|
new_width = previous_client_area.Width;
|
|
|
|
|
new_height = previous_client_area.Height;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WindowState.Minimized:
|
|
|
|
|
command = ShowWindowCommand.SHOWMINIMIZED;
|
|
|
|
|
flags |= SetWindowPosFlags.NOSIZE;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WindowState.Maximized:
|
|
|
|
|
case WindowState.Fullscreen:
|
|
|
|
|
if (windowState == WindowState.Normal || windowState == WindowState.Minimized)
|
|
|
|
|
{
|
|
|
|
|
// Get the normal size of the window, so we can set it when reverting from fullscreen/maximized to normal.
|
|
|
|
|
previous_client_area = new Rectangle(width, height);
|
|
|
|
|
previous_window_border = windowBorder;
|
|
|
|
|
//Functions.AdjustWindowRect(ref previous_client_area, WindowStyle.OverlappedWindow, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
command = ShowWindowCommand.SHOWMAXIMIZED;
|
|
|
|
|
flags |= SetWindowPosFlags.SHOWWINDOW | SetWindowPosFlags.DRAWFRAME | SetWindowPosFlags.NOSIZE;
|
|
|
|
|
|
|
|
|
|
if (value == WindowState.Fullscreen)
|
|
|
|
|
windowBorder = WindowBorder.Hidden;
|
|
|
|
|
else
|
|
|
|
|
windowBorder = previous_window_border;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Functions.ShowWindow(Handle, command);
|
|
|
|
|
Functions.SetWindowPos(Handle, WindowPlacementOptions.TOP, 0, 0, new_width, new_height, flags);
|
|
|
|
|
|
|
|
|
|
windowState = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
2008-04-13 21:32:04 +00:00
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
#region public WindowBorder WindowBorder
|
|
|
|
|
|
|
|
|
|
public WindowBorder WindowBorder
|
2008-04-13 21:32:04 +00:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
return windowBorder;
|
2008-04-13 21:32:04 +00:00
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
if (windowBorder == value)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
WindowStyle style = WindowStyle.ClipChildren | WindowStyle.ClipSiblings;
|
|
|
|
|
|
|
|
|
|
switch (value)
|
|
|
|
|
{
|
|
|
|
|
case WindowBorder.Resizable:
|
|
|
|
|
style |= WindowStyle.OverlappedWindow;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WindowBorder.Fixed:
|
|
|
|
|
style &= ~(WindowStyle.MaximizeBox | WindowStyle.ThickFrame | WindowStyle.SizeBox);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case WindowBorder.Hidden:
|
|
|
|
|
style &= WindowStyle.Popup;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Functions.SetWindowLong(Handle, GetWindowLongOffsets.STYLE, (IntPtr)(int)style);
|
|
|
|
|
|
2008-04-13 21:32:04 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region --- IResizable Members ---
|
|
|
|
|
|
|
|
|
|
#region public int Width
|
|
|
|
|
|
2008-01-23 13:26:14 +00:00
|
|
|
|
/// <summary>Gets a System.Int32 containing the Width of this GameWindow.</summary>
|
2007-07-23 00:15:18 +00:00
|
|
|
|
public int Width
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
return client_rectangle.Width;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
if (value <= 0) throw new ArgumentOutOfRangeException("Window width must be higher than zero.");
|
|
|
|
|
//if (WindowState == WindowState.Fullscreen || WindowState == WindowState.Maximized)
|
|
|
|
|
// throw new InvalidOperationException("Cannot resize a fullscreen or maximized window.");
|
|
|
|
|
Functions.SetWindowPos(Handle, WindowPlacementOptions.TOP, 0, 0, value, Height, SetWindowPosFlags.NOMOVE);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region public int Height
|
|
|
|
|
|
2008-01-23 13:26:14 +00:00
|
|
|
|
/// <summary>Gets a System.Int32 containing the Heights of this GameWindow.</summary>
|
2007-07-23 00:15:18 +00:00
|
|
|
|
public int Height
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
return client_rectangle.Height;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
if (value <= 0) throw new ArgumentOutOfRangeException("Window height must be higher than zero.");
|
|
|
|
|
Functions.SetWindowPos(Handle, WindowPlacementOptions.TOP, 0, 0, Width, value, SetWindowPosFlags.NOMOVE);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-09-26 11:55:55 +00:00
|
|
|
|
#region public void OnResize
|
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
public event ResizeEvent Resize = null;
|
2007-09-26 11:55:55 +00:00
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
public void OnResize(ResizeEventArgs e)
|
|
|
|
|
{
|
2008-04-20 17:54:16 +00:00
|
|
|
|
throw new NotImplementedException("Use GameWindow.OnResize instead.");
|
|
|
|
|
//this.width = e.Width;
|
|
|
|
|
//this.height = e.Height;
|
|
|
|
|
//if (this.Resize != null)
|
|
|
|
|
// this.Resize(this, e);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
#region Top, Bottom, Left and Right
|
|
|
|
|
|
2007-08-21 12:04:01 +00:00
|
|
|
|
public int Top
|
|
|
|
|
{
|
|
|
|
|
get { return top; }
|
|
|
|
|
private set { top = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Bottom
|
|
|
|
|
{
|
|
|
|
|
get { return bottom; }
|
|
|
|
|
private set { bottom = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Left
|
|
|
|
|
{
|
|
|
|
|
get { return left; }
|
|
|
|
|
private set { left = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Right
|
|
|
|
|
{
|
|
|
|
|
get { return right; }
|
|
|
|
|
private set { right = value; }
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
#endregion
|
2007-08-22 00:30:16 +00:00
|
|
|
|
|
2008-04-20 17:54:16 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2007-08-22 00:30:16 +00:00
|
|
|
|
#region --- IDisposable Members ---
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
this.Dispose(true);
|
2007-09-02 00:16:22 +00:00
|
|
|
|
//GC.SuppressFinalize(this);
|
2007-08-22 00:30:16 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Dispose(bool calledManually)
|
|
|
|
|
{
|
|
|
|
|
if (!disposed)
|
|
|
|
|
{
|
|
|
|
|
// Clean unmanaged resources here:
|
|
|
|
|
|
|
|
|
|
if (calledManually)
|
|
|
|
|
{
|
|
|
|
|
// Safe to clean managed resources
|
2007-09-02 00:16:22 +00:00
|
|
|
|
//base.DestroyHandle();
|
2007-08-22 00:30:16 +00:00
|
|
|
|
}
|
|
|
|
|
disposed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-09-02 00:16:22 +00:00
|
|
|
|
/*
|
2007-08-22 00:30:16 +00:00
|
|
|
|
~WinGLNative()
|
|
|
|
|
{
|
|
|
|
|
Dispose(false);
|
|
|
|
|
}
|
2007-09-02 00:16:22 +00:00
|
|
|
|
*/
|
2007-08-22 00:30:16 +00:00
|
|
|
|
#endregion
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region class WindowHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
class WindowHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
|
|
|
|
{
|
|
|
|
|
protected override bool ReleaseHandle()
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("The method or operation is not implemented.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool IsInvalid
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return base.IsInvalid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|