Squashed 'FSI.Lib/' content from commit 6aa4846
git-subtree-dir: FSI.Lib git-subtree-split: 6aa48465a834a7bfdd9cbeae8d2e4f769d0c0ff8
This commit is contained in:
138
FSI.Lib/Wpf/WindowExtensions.cs
Normal file
138
FSI.Lib/Wpf/WindowExtensions.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
|
||||
namespace FSI.Lib.Wpf.ExtensionMethods
|
||||
{
|
||||
public static class WindowExtensions
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
public static bool ActivateCenteredToMouse(this Window window)
|
||||
{
|
||||
ComputeTopLeft(ref window);
|
||||
return window.Activate();
|
||||
}
|
||||
|
||||
public static void ShowCenteredToMouse(this Window window)
|
||||
{
|
||||
// in case the default start-up location isn't set to Manual
|
||||
WindowStartupLocation oldLocation = window.WindowStartupLocation;
|
||||
// set location to manual -> window will be placed by Top and Left property
|
||||
window.WindowStartupLocation = WindowStartupLocation.Manual;
|
||||
ComputeTopLeft(ref window);
|
||||
window.Show();
|
||||
window.WindowStartupLocation = oldLocation;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
private static void ComputeTopLeft(ref Window window)
|
||||
{
|
||||
W32Point pt = new W32Point();
|
||||
if (!GetCursorPos(ref pt))
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
|
||||
}
|
||||
|
||||
// 0x00000002: return nearest monitor if pt is not contained in any monitor.
|
||||
IntPtr monHandle = MonitorFromPoint(pt, 0x00000002);
|
||||
W32MonitorInfo monInfo = new W32MonitorInfo();
|
||||
monInfo.Size = Marshal.SizeOf(typeof(W32MonitorInfo));
|
||||
|
||||
if (!GetMonitorInfo(monHandle, ref monInfo))
|
||||
{
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
|
||||
}
|
||||
|
||||
// use WorkArea struct to include the taskbar position.
|
||||
W32Rect monitor = monInfo.WorkArea;
|
||||
double offsetX = Math.Round(window.Width / 2);
|
||||
double offsetY = Math.Round(window.Height / 2);
|
||||
|
||||
double top = pt.Y - offsetY;
|
||||
double left = pt.X - offsetX;
|
||||
|
||||
Rect screen = new Rect(
|
||||
new Point(monitor.Left, monitor.Top),
|
||||
new Point(monitor.Right, monitor.Bottom));
|
||||
Rect wnd = new Rect(
|
||||
new Point(left, top),
|
||||
new Point(left + window.Width, top + window.Height));
|
||||
|
||||
window.Top = wnd.Top;
|
||||
window.Left = wnd.Left;
|
||||
|
||||
if (!screen.Contains(wnd))
|
||||
{
|
||||
if (wnd.Top < screen.Top)
|
||||
{
|
||||
double diff = Math.Abs(screen.Top - wnd.Top);
|
||||
window.Top = wnd.Top + diff;
|
||||
}
|
||||
|
||||
if (wnd.Bottom > screen.Bottom)
|
||||
{
|
||||
double diff = wnd.Bottom - screen.Bottom;
|
||||
window.Top = wnd.Top - diff;
|
||||
}
|
||||
|
||||
if (wnd.Left < screen.Left)
|
||||
{
|
||||
double diff = Math.Abs(screen.Left - wnd.Left);
|
||||
window.Left = wnd.Left + diff;
|
||||
}
|
||||
|
||||
if (wnd.Right > screen.Right)
|
||||
{
|
||||
double diff = wnd.Right - screen.Right;
|
||||
window.Left = wnd.Left - diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region W32 API
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetCursorPos(ref W32Point pt);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref W32MonitorInfo lpmi);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr MonitorFromPoint(W32Point pt, uint dwFlags);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct W32Point
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct W32MonitorInfo
|
||||
{
|
||||
public int Size;
|
||||
public W32Rect Monitor;
|
||||
public W32Rect WorkArea;
|
||||
public uint Flags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct W32Rect
|
||||
{
|
||||
public int Left;
|
||||
public int Top;
|
||||
public int Right;
|
||||
public int Bottom;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user