private static Size MonitorSize(ref Window window, Matrix dpimatrix, bool full = false) { W32Point pt = new W32Point(); pt.X = (int)(window.Left + (window.Width) / 2); pt.Y = (int)(window.Height + (window.Height) / 2); IntPtr monHandle = MonitorFromWindow(new WindowInteropHelper(window).Handle, 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; if (full) { monitor = monInfo.Monitor; } return((Size)dpimatrix.Transform(new Vector(Math.Abs(monitor.Right - monitor.Left), Math.Abs(monitor.Bottom - monitor.Top)))); }
public static void PlaceNearCursor(this 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()); } W32Rect workArea = monInfo.WorkArea; var wpfScreenTopLeft = window.RealPixelsToWpf(new Point(workArea.Left, workArea.Top)); var wpfScreenBottomRight = window.RealPixelsToWpf(new Point(workArea.Right, workArea.Bottom)); var wpfPt = RealPixelsToWpf(window, new Point(pt.X, pt.Y)); const int OFFSET = 10; var xPosRight = wpfPt.X + window.Width + OFFSET; if (xPosRight > wpfScreenBottomRight.X) { var xPosLeft = wpfPt.X - window.Width - OFFSET; if (xPosLeft < wpfScreenTopLeft.X) { window.Left = wpfScreenTopLeft.X + OFFSET; } else { window.Left = xPosLeft; } } else { window.Left = wpfPt.X + OFFSET; } var yPosBottom = wpfPt.Y + window.Height + OFFSET; if (yPosBottom > wpfScreenBottomRight.Y) { var yPosTop = wpfPt.Y - window.Height - OFFSET; if (yPosTop < wpfScreenTopLeft.Y) { window.Top = wpfScreenTopLeft.Y + OFFSET; } else { window.Top = yPosTop; } } else { window.Top = wpfPt.Y + OFFSET; } }
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref W32MonitorInfo lpmi);
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; } } }