Fixed ClassName and ModalLoopTimerId when constructing multiple WinGLNative windows in parallel.

WinGLNative windows are now correctly focused when clicked on the client area.
This commit is contained in:
the_fiddler 2009-11-03 23:42:06 +00:00
parent 2ba3e5357e
commit eec0033297
2 changed files with 45 additions and 12 deletions

View file

@ -941,6 +941,9 @@ namespace OpenTK.Platform.Windows
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetCapture(); public static extern IntPtr GetCapture();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr SetFocus(IntPtr hwnd);
#region Async input #region Async input
#region GetCursorPos #region GetCursorPos
@ -4104,6 +4107,18 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region MouseActivate
enum MouseActivate
{
ACTIVATE = 1,
ACTIVATEANDEAT = 2,
NOACTIVATE = 3,
NOACTIVATEANDEAT = 4,
}
#endregion
#endregion #endregion
#region --- Callbacks --- #region --- Callbacks ---

View file

@ -45,13 +45,15 @@ namespace OpenTK.Platform.Windows
{ {
#region Fields #region Fields
readonly static object SyncRoot = new object();
readonly static ExtendedWindowStyle ParentStyleEx = ExtendedWindowStyle.WindowEdge; readonly static ExtendedWindowStyle ParentStyleEx = ExtendedWindowStyle.WindowEdge;
readonly static ExtendedWindowStyle ChildStyleEx = 0; readonly static ExtendedWindowStyle ChildStyleEx = 0;
readonly IntPtr Instance = Marshal.GetHINSTANCE(typeof(WinGLNative).Module); readonly IntPtr Instance = Marshal.GetHINSTANCE(typeof(WinGLNative).Module);
readonly IntPtr ClassName = Marshal.StringToHGlobalAuto("OpenTK.INativeWindow" + WindowCount++.ToString()); readonly IntPtr ClassName;
readonly WindowProcedure WindowProcedureDelegate; readonly WindowProcedure WindowProcedureDelegate;
readonly UIntPtr ModalLoopTimerId = new UIntPtr(1); readonly UIntPtr ModalLoopTimerId;
readonly uint ModalLoopTimerPeriod = 1; readonly uint ModalLoopTimerPeriod = 1;
UIntPtr timer_handle; UIntPtr timer_handle;
readonly Functions.TimerProc ModalLoopCallback; readonly Functions.TimerProc ModalLoopCallback;
@ -73,12 +75,10 @@ namespace OpenTK.Platform.Windows
previous_bounds = new Rectangle(); // Used to restore previous size when leaving fullscreen mode. previous_bounds = new Rectangle(); // Used to restore previous size when leaving fullscreen mode.
Icon icon; Icon icon;
static readonly ClassStyle ClassStyle = const ClassStyle DefaultClassStyle =
ClassStyle.OwnDC | ClassStyle.VRedraw | ClassStyle.HRedraw | ClassStyle.Ime; ClassStyle.OwnDC | ClassStyle.VRedraw | ClassStyle.HRedraw | ClassStyle.Ime;
static int WindowCount = 0; // Used to create unique window class names. readonly IntPtr DefaultWindowProcedure =
IntPtr DefaultWindowProcedure =
Marshal.GetFunctionPointerForDelegate(new WindowProcedure(Functions.DefWindowProc)); Marshal.GetFunctionPointerForDelegate(new WindowProcedure(Functions.DefWindowProc));
// Used for IInputDriver implementation // Used for IInputDriver implementation
@ -93,12 +93,21 @@ namespace OpenTK.Platform.Windows
KeyPressEventArgs key_press = new KeyPressEventArgs((char)0); KeyPressEventArgs key_press = new KeyPressEventArgs((char)0);
static int window_count;
#endregion #endregion
#region Contructors #region Contructors
public WinGLNative(int x, int y, int width, int height, string title, GameWindowFlags options, DisplayDevice device) public WinGLNative(int x, int y, int width, int height, string title, GameWindowFlags options, DisplayDevice device)
{ {
lock (SyncRoot)
{
++window_count;
ClassName = Marshal.StringToHGlobalAuto(typeof(WinGLNative).Name + window_count.ToString());
ModalLoopTimerId = new UIntPtr((uint)window_count);
}
// This is the main window procedure callback. We need the callback in order to create the window, so // This is the main window procedure callback. We need the callback in order to create the window, so
// don't move it below the CreateWindow calls. // don't move it below the CreateWindow calls.
WindowProcedureDelegate = WindowProcedure; WindowProcedureDelegate = WindowProcedure;
@ -143,8 +152,6 @@ namespace OpenTK.Platform.Windows
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{ {
bool mouse_left = false;
switch (message) switch (message)
{ {
#region Size / Move / Style events #region Size / Move / Style events
@ -160,7 +167,7 @@ namespace OpenTK.Platform.Windows
if (new_focused_state != Focused && FocusedChanged != null) if (new_focused_state != Focused && FocusedChanged != null)
FocusedChanged(this, EventArgs.Empty); FocusedChanged(this, EventArgs.Empty);
break; return IntPtr.Zero;
case WindowMessage.ENTERMENULOOP: case WindowMessage.ENTERMENULOOP:
case WindowMessage.ENTERSIZEMOVE: case WindowMessage.ENTERSIZEMOVE:
@ -307,6 +314,7 @@ namespace OpenTK.Platform.Windows
} }
else if (Functions.GetCapture() != window.WindowHandle) else if (Functions.GetCapture() != window.WindowHandle)
{ {
Functions.SetFocus(window.WindowHandle);
Functions.SetCapture(window.WindowHandle); Functions.SetCapture(window.WindowHandle);
if (MouseEnter != null) if (MouseEnter != null)
MouseEnter(this, EventArgs.Empty); MouseEnter(this, EventArgs.Empty);
@ -542,7 +550,7 @@ namespace OpenTK.Platform.Windows
{ {
ExtendedWindowClass wc = new ExtendedWindowClass(); ExtendedWindowClass wc = new ExtendedWindowClass();
wc.Size = ExtendedWindowClass.SizeInBytes; wc.Size = ExtendedWindowClass.SizeInBytes;
wc.Style = ClassStyle; wc.Style = DefaultClassStyle;
wc.Instance = Instance; wc.Instance = Instance;
wc.WndProc = WindowProcedureDelegate; wc.WndProc = WindowProcedureDelegate;
wc.ClassName = ClassName; wc.ClassName = ClassName;
@ -552,7 +560,17 @@ namespace OpenTK.Platform.Windows
ushort atom = Functions.RegisterClassEx(ref wc); ushort atom = Functions.RegisterClassEx(ref wc);
if (atom == 0) if (atom == 0)
throw new PlatformException(String.Format("Failed to register window class. Error: {0}", Marshal.GetLastWin32Error())); {
int error= Marshal.GetLastWin32Error();
Debug.Print("Failed to register class {0}, due to error {1}.", Marshal.PtrToStringAuto(ClassName), error);
// Error 1410 means "class already exists", which means we'll just go ahead and use it.
// In all other cases, we'll throw an exception and stop execution.
if (error != 1410)
{
throw new PlatformException(String.Format("Failed to register window class. Error: {0}", error));
}
}
class_registered = true; class_registered = true;
} }