Skip to content

Instantly share code, notes, and snippets.

@emoacht
Created December 5, 2022 23:36
Show Gist options
  • Save emoacht/bb085f26429439152f55135eca02a6d9 to your computer and use it in GitHub Desktop.
Save emoacht/bb085f26429439152f55135eca02a6d9 to your computer and use it in GitHub Desktop.
Moves a specified Window to the center of a monitor where the cursor locates.
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
public static class WindowHelper
{
/// <summary>
/// Moves a specified Window to the center of a monitor where the cursor locates.
/// </summary>
/// <param name="window">Window to be moved</param>
/// <returns>
/// This should be called before Loaded event such as ArrangeOverride method.
/// </returns>
public static bool MoveToCenter(Window window)
{
if (window.WindowStartupLocation != WindowStartupLocation.CenterScreen)
return false;
if (window.IsLoaded)
return false;
return MoveToCenterBase(window);
}
public static bool MoveToCenterBase(Window window)
{
if (!GetCursorPos(out POINT cursorPoint))
return false;
var monitorHandle = MonitorFromPoint(
cursorPoint,
MONITOR_DEFAULTTO.MONITOR_DEFAULTTONULL);
if (monitorHandle == IntPtr.Zero)
return false;
var monitorInfo = new MONITORINFO() { cbSize = (uint)Marshal.SizeOf<MONITORINFO>() };
if (!GetMonitorInfo(
monitorHandle,
ref monitorInfo))
{
return false;
}
var windowHandle = new WindowInteropHelper(window).EnsureHandle();
if (windowHandle == IntPtr.Zero)
return false;
if (!GetWindowPlacement(
windowHandle,
out WINDOWPLACEMENT windowPlacement))
{
return false;
}
int left = monitorInfo.rcWork.left + Math.Max(0, (int)((monitorInfo.rcWork.Width - windowPlacement.rcNormalPosition.Width) / 2D));
int top = monitorInfo.rcWork.top + Math.Max(0, (int)((monitorInfo.rcWork.Height - windowPlacement.rcNormalPosition.Height) / 2D));
windowPlacement.rcNormalPosition = new RECT(left, top, width: windowPlacement.rcNormalPosition.Width, height: windowPlacement.rcNormalPosition.Height);
return SetWindowPlacement(
windowHandle,
ref windowPlacement);
}
#region Win32
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetCursorPos(
out POINT lpPoint);
[DllImport("User32.dll")]
private static extern IntPtr MonitorFromPoint(
POINT pt,
MONITOR_DEFAULTTO dwFlags);
private enum MONITOR_DEFAULTTO : uint
{
MONITOR_DEFAULTTONULL = 0x00000000,
MONITOR_DEFAULTTOPRIMARY = 0x00000001,
MONITOR_DEFAULTTONEAREST = 0x00000002,
}
[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetMonitorInfo(
IntPtr hMonitor,
ref MONITORINFO lpmi);
[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowPlacement(
IntPtr hWnd,
out WINDOWPLACEMENT lpwndpl);
[DllImport("User32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetWindowPlacement(
IntPtr hWnd,
[In] ref WINDOWPLACEMENT lpwndpl);
[StructLayout(LayoutKind.Sequential)]
private struct WINDOWPLACEMENT
{
public uint length;
public uint flags;
public uint showCmd;
public POINT ptMinPosition;
public POINT ptMaxPosition;
public RECT rcNormalPosition;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
public int Width => right - left;
public int Height => bottom - top;
public RECT(int x, int y, int width, int height)
{
left = x;
top = y;
right = x + width;
bottom = y + height;
}
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment