Browse Source

Prevent popup from deactivating parent window.

pull/39/head
Steven Kirk 11 years ago
parent
commit
e2a67e42c7
  1. 2
      Perspex.Controls/Platform/ITopLevelImpl.cs
  2. 11
      Perspex.Controls/TopLevel.cs
  3. 8
      Windows/Perspex.Win32/Interop/UnmanagedMethods.cs
  4. 14
      Windows/Perspex.Win32/PopupImpl.cs
  5. 109
      Windows/Perspex.Win32/WindowImpl.cs

2
Perspex.Controls/Platform/ITopLevelImpl.cs

@ -21,6 +21,8 @@ namespace Perspex.Platform
Action Closed { get; set; }
Action Deactivated { get; set; }
Action<RawInputEventArgs> Input { get; set; }
Action<Rect, IPlatformHandle> Paint { get; set; }

11
Perspex.Controls/TopLevel.cs

@ -80,6 +80,7 @@ namespace Perspex.Controls
this.PlatformImpl.SetOwner(this);
this.PlatformImpl.Activated = this.HandleActivated;
this.PlatformImpl.Deactivated = this.HandleDeactivated;
this.PlatformImpl.Closed = this.HandleClosed;
this.PlatformImpl.Input = this.HandleInput;
this.PlatformImpl.Paint = this.HandlePaint;
@ -104,6 +105,8 @@ namespace Perspex.Controls
public event EventHandler Closed;
public event EventHandler Deactivated;
public Size ClientSize
{
get { return this.GetValue(ClientSizeProperty); }
@ -175,6 +178,14 @@ namespace Perspex.Controls
}
}
private void HandleDeactivated()
{
if (this.Deactivated != null)
{
this.Deactivated(this, EventArgs.Empty);
}
}
private void HandleInput(RawInputEventArgs e)
{
this.inputManager.Process(e);

8
Windows/Perspex.Win32/Interop/UnmanagedMethods.cs

@ -42,6 +42,14 @@ namespace Perspex.Win32.Interop
IDC_HELP = 32651
}
public enum MouseActivate : int
{
MA_ACTIVATE = 1,
MA_ACTIVATEANDEAT = 2,
MA_NOACTIVATE = 3,
MA_NOACTIVATEANDEAT = 4
}
[Flags]
public enum SetWindowPosFlags : uint
{

14
Windows/Perspex.Win32/PopupImpl.cs

@ -38,8 +38,7 @@ namespace Perspex.Win32
UnmanagedMethods.WindowStyles exStyle =
UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW |
UnmanagedMethods.WindowStyles.WS_EX_TOPMOST |
UnmanagedMethods.WindowStyles.WS_EX_NOACTIVATE;
UnmanagedMethods.WindowStyles.WS_EX_TOPMOST;
return UnmanagedMethods.CreateWindowEx(
(int)exStyle,
@ -55,5 +54,16 @@ namespace Perspex.Win32
IntPtr.Zero,
IntPtr.Zero);
}
protected override IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
switch ((UnmanagedMethods.WindowsMessage)msg)
{
case UnmanagedMethods.WindowsMessage.WM_MOUSEACTIVATE:
return (IntPtr)UnmanagedMethods.MouseActivate.MA_NOACTIVATE;
default:
return base.WndProc(hWnd, msg, wParam, lParam);
}
}
}
}

109
Windows/Perspex.Win32/WindowImpl.cs

@ -37,6 +37,8 @@ namespace Perspex.Win32
public Action Closed { get; set; }
public Action Deactivated { get; set; }
public Action<RawInputEventArgs> Input { get; set; }
public Action<Rect, IPlatformHandle> Paint { get; set; }
@ -148,50 +150,8 @@ namespace Perspex.Win32
IntPtr.Zero);
}
private void CreateWindow()
{
// Ensure that the delegate doesn't get garbage collected by storing it as a field.
this.wndProcDelegate = new UnmanagedMethods.WndProc(this.WndProc);
this.className = Guid.NewGuid().ToString();
UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX
{
cbSize = Marshal.SizeOf(typeof(UnmanagedMethods.WNDCLASSEX)),
style = 0,
lpfnWndProc = this.wndProcDelegate,
hInstance = Marshal.GetHINSTANCE(this.GetType().Module),
hCursor = UnmanagedMethods.LoadCursor(IntPtr.Zero, (int)UnmanagedMethods.Cursor.IDC_ARROW),
hbrBackground = (IntPtr)5,
lpszClassName = this.className,
};
ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx);
if (atom == 0)
{
throw new Win32Exception();
}
this.hwnd = this.CreateWindowOverride(atom);
if (this.hwnd == IntPtr.Zero)
{
throw new Win32Exception();
}
this.Handle = new PlatformHandle(this.hwnd, "HWND");
}
private Point ScreenToClient(uint x, uint y)
{
var p = new UnmanagedMethods.POINT { X = (int)x, Y = (int)y };
UnmanagedMethods.ScreenToClient(this.hwnd, ref p);
return new Point(p.X, p.Y);
}
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")]
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
protected virtual IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
const double WheelDelta = 120.0;
uint timestamp = unchecked((uint)UnmanagedMethods.GetMessageTime());
@ -203,9 +163,23 @@ namespace Perspex.Win32
switch ((UnmanagedMethods.WindowsMessage)msg)
{
case UnmanagedMethods.WindowsMessage.WM_ACTIVATE:
if (this.Activated != null)
switch ((int)lParam & 0xffff)
{
this.Activated();
case 1:
case 2:
if (this.Activated != null)
{
this.Activated();
}
break;
case 0:
if (this.Deactivated != null)
{
this.Deactivated();
}
break;
}
return IntPtr.Zero;
@ -304,7 +278,7 @@ namespace Perspex.Win32
case UnmanagedMethods.WindowsMessage.WM_SIZE:
if (this.Resized != null)
{
{
var clientSize = new Size((int)lParam & 0xffff, (int)lParam >> 16);
this.Resized(clientSize);
}
@ -320,5 +294,48 @@ namespace Perspex.Win32
return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam);
}
private void CreateWindow()
{
// Ensure that the delegate doesn't get garbage collected by storing it as a field.
this.wndProcDelegate = new UnmanagedMethods.WndProc(this.WndProc);
this.className = Guid.NewGuid().ToString();
UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX
{
cbSize = Marshal.SizeOf(typeof(UnmanagedMethods.WNDCLASSEX)),
style = 0,
lpfnWndProc = this.wndProcDelegate,
hInstance = Marshal.GetHINSTANCE(this.GetType().Module),
hCursor = UnmanagedMethods.LoadCursor(IntPtr.Zero, (int)UnmanagedMethods.Cursor.IDC_ARROW),
hbrBackground = (IntPtr)5,
lpszClassName = this.className,
};
ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx);
if (atom == 0)
{
throw new Win32Exception();
}
this.hwnd = this.CreateWindowOverride(atom);
if (this.hwnd == IntPtr.Zero)
{
throw new Win32Exception();
}
this.Handle = new PlatformHandle(this.hwnd, "HWND");
}
private Point ScreenToClient(uint x, uint y)
{
var p = new UnmanagedMethods.POINT { X = (int)x, Y = (int)y };
UnmanagedMethods.ScreenToClient(this.hwnd, ref p);
return new Point(p.X, p.Y);
}
}
}

Loading…
Cancel
Save