123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- using System.Drawing;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Windows.Interop;
- namespace System.Windows.Forms
- {
- public enum SizingAction
- {
- None = 0,
- North = 3,
- South = 6,
- East = 2,
- West = 1,
- NorthEast = 5,
- NorthWest = 4,
- SouthEast = 8,
- SouthWest = 7
- }
- internal static class NativeMethods
- {
- const int WM_SYSCOMMAND = 0x112;
- const int SC_SIZE = 0xF000;
- const int GWL_STYLE = -16;
- const int GWL_EXSTYLE = -20;
- const int WS_EX_DLGMODALFRAME = 0x0001;
- const int SW_MAXIMIZE = 3;
- const int WS_MAXIMIZEBOX = 0x10000;
- const int WS_MINIMIZEBOX = 0x20000;
- const int WM_SETICON = 0x0080;
- [DllImport("user32.dll", SetLastError = true)]
- private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
- [DllImport("user32.dll")]
- static extern int GetWindowLong(IntPtr hwnd, int index);
- [DllImport("user32.dll")]
- static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle);
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- internal static extern bool GetCursorPos(ref Win32Point pt);
- [DllImport("user32.dll")]
- public static extern int GetDoubleClickTime();
- [DllImport("user32.dll")]
- private extern static int GetWindowRect(IntPtr hWnd, ref RECT lpRect);
- [DllImport("user32.dll")]
- private extern static int GetClientRect(IntPtr hWnd, ref RECT lpRect);
- [DllImport("user32.dll")]
- private static extern IntPtr MonitorFromPoint(Win32Point pt, int flags);
- [DllImport("user32.dll", SetLastError = true)]
- public static extern IntPtr MonitorFromWindow(HandleRef handle, int flags);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- public static extern bool GetMonitorInfo(HandleRef hmonitor, [In][Out] MONITORINFOEX info);
- [DllImport("user32.dll")]
- public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData);
- public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
- [DllImport("dwmapi.dll", PreserveSig = true)]
- private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
- [DllImport("dwmapi.dll")]
- private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref NativeMethods.RECT pMarInset);
- [StructLayout(LayoutKind.Sequential)]
- public struct Win32Point
- {
- public Int32 X;
- public Int32 Y;
- };
- [StructLayout(LayoutKind.Sequential)]
- public struct RECT
- {
- public int left;
- public int top;
- public int right;
- public int bottom;
- public int Width => right - left;
- public int Height => bottom - top;
- }
-
- [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
- public class MONITORINFOEX
- {
- internal int cbSize = SizeOf();
- internal RECT rcMonitor;
- internal RECT rcWork;
- internal int dwFlags;
- [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
- internal char[] szDevice = new char[32];
- private static int SizeOf() => Marshal.SizeOf(typeof(MONITORINFOEX));
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct MINMAXINFO
- {
- public Win32Point ptReserved;
- public Win32Point ptMaxSize;
- public Win32Point ptMaxPosition;
- public Win32Point ptMinTrackSize;
- public Win32Point ptMaxTrackSize;
- };
- [StructLayout(LayoutKind.Sequential)]
- private struct WINDOWPLACEMENT
- {
- public int length;
- public int flags;
- public int showCmd;
- public Win32Point ptMinPosition;
- public Win32Point ptMaxPosition;
- public RECT rcNormalPosition;
- public RECT rcDevice;
- }
- [DllImport("user32.dll")]
- private static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
- public static bool IsWindowMaximized(IntPtr hWnd)
- {
- var wpl = new WINDOWPLACEMENT();
- GetWindowPlacement(hWnd, ref wpl);
- return wpl.showCmd == SW_MAXIMIZE;
- }
- [DllImport("user32.dll")]
- private static extern IntPtr GetActiveWindow();
- public static Window ActiveWindow()
- {
- IntPtr active = GetActiveWindow();
- return System.Windows.Application.Current.Windows.OfType<System.Windows.Window>()
- .SingleOrDefault(window => new WindowInteropHelper(window).Handle == active);
- }
- [DllImport("Shcore.dll")]
- private static extern IntPtr GetDpiForMonitor([In] IntPtr hmonitor, [In] uint dpiType, [Out] out uint dpiX, [Out] out uint dpiY);
- public static int GetDpiForMonitor(IntPtr mon)
- {
- try
- {
- GetDpiForMonitor(mon, 0, out uint dpiX, out uint dpiY);
- return (int)dpiX;
- }
- catch
- {
- using (Graphics gr = Graphics.FromHwnd(IntPtr.Zero))
- return (int)gr.DpiX;
- }
- }
- public static void MoveWindow(Form form, Rectangle rect)
- {
- IntPtr handle = new WindowInteropHelper(form.window).EnsureHandle();
- // The first move puts it on the correct monitor, which triggers WM_DPICHANGED
- // The +1/-1 coerces WPF to update Window.Top/Left/Width/Height in the second move
- MoveWindow(handle, rect.Left + 1, rect.Top, rect.Width - 1, rect.Height, false);
- MoveWindow(handle, rect.Left, rect.Top, rect.Width, rect.Height, true);
- }
- public static Drawing.Point GetMousePosition()
- {
- var w32Mouse = new Win32Point();
- GetCursorPos(ref w32Mouse);
- return new Drawing.Point(w32Mouse.X, w32Mouse.Y);
- }
- public static IntPtr GetCurrentMonitorFromMousePosition()
- {
- var w32Mouse = new Win32Point();
- GetCursorPos(ref w32Mouse);
- return MonitorFromPoint(w32Mouse, 2);
- }
- public static IntPtr GetMonitorFromPoint(int x, int y)
- {
- return MonitorFromPoint(new Win32Point() { X = x, Y = y }, 2);
- }
- public static RECT WorkAreaBoundsForMointor(IntPtr hMonitor)
- {
- MONITORINFOEX info = new MONITORINFOEX();
- GetMonitorInfo(new HandleRef(null, hMonitor), info);
- return info.rcWork;
- }
- public static Drawing.Size GetClientSizeDelta(Window window)
- {
- IntPtr handle = new WindowInteropHelper(window).EnsureHandle();
- RECT rect = new RECT();
- GetWindowRect(handle, ref rect);
- RECT clientRect = new RECT();
- GetClientRect(handle, ref clientRect);
-
- return new Drawing.Size(rect.Width - clientRect.Width, rect.Height - clientRect.Height);
- }
- public static void RemoveWindowItems(Window window, bool icon, bool minimize, bool maximize)
- {
- IntPtr hwnd = new WindowInteropHelper(window).EnsureHandle();
- if (!icon)
- {
- int extendedStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
- SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle | WS_EX_DLGMODALFRAME);
- // this removes icon if it is set in app resources (case: the WpfDemo)
- SendMessage(hwnd, WM_SETICON, new IntPtr(1), IntPtr.Zero);
- SendMessage(hwnd, WM_SETICON, IntPtr.Zero, IntPtr.Zero);
- }
- if (!minimize || !maximize)
- {
- int currentStyle = GetWindowLong(hwnd, GWL_STYLE);
- if (!minimize)
- currentStyle &= ~WS_MINIMIZEBOX;
- if (!maximize)
- currentStyle &= ~WS_MAXIMIZEBOX;
- SetWindowLong(hwnd, GWL_STYLE, currentStyle);
- }
- }
- public static void DragSize(IntPtr handle, SizingAction sizingAction)
- {
- SendMessage(handle, WM_SYSCOMMAND, (IntPtr)(SC_SIZE + sizingAction), IntPtr.Zero);
- }
- public static bool DropShadow(IntPtr handle, bool shadow)
- {
- try
- {
- int val = 2;
- int ret1 = DwmSetWindowAttribute(handle, 2, ref val, 4);
- if (ret1 == 0)
- {
- var m = new RECT { left = 0, top = shadow ? 1 : 0, right = 0, bottom = 0 };
- int ret2 = DwmExtendFrameIntoClientArea(handle, ref m);
- return ret2 == 0;
- }
- else
- {
- return false;
- }
- }
- catch
- {
- // Probably dwmapi.dll not found (incompatible OS)
- return false;
- }
- }
- }
- }
|