private Screen(IntPtr monitor, IntPtr hdc) { if (!multiMonitorSupport || monitor == (IntPtr)PRIMARY_MONITOR) { this.Bounds = SystemInformation.VirtualScreen; this.Primary = true; this.DeviceName = "DISPLAY"; } else { var info = new NativeMethods.MONITORINFOEX(); NativeMethods.GetMonitorInfo(new HandleRef(null, monitor), info); this.Bounds = new Rect( info.rcMonitor.left, info.rcMonitor.top, info.rcMonitor.right - info.rcMonitor.left, info.rcMonitor.bottom - info.rcMonitor.top); this.Primary = ((info.dwFlags & MONITORINFOF_PRIMARY) != 0); this.DeviceName = new string(info.szDevice).TrimEnd((char)0); } hmonitor = monitor; }
private Point TransformWorkAreaScreenArea(Point pt, TransformType transformType) { int deltaX = 0; int deltaY = 0; Point retPt; if (!_inTrustedSubWindow) { SecurityHelper.DemandUIWindowPermission(); } // First we get the monitor on which the window is on. [Get/Set]WindowPlacement // co-ods are dependent on the monitor on which the window is on. IntPtr hMonitor = SafeNativeMethods.MonitorFromWindow(new HandleRef(this, CriticalHandle), NativeMethods.MONITOR_DEFAULTTONULL); if (hMonitor != IntPtr.Zero) { NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX(); monitorInfo.cbSize = Marshal.SizeOf(typeof(NativeMethods.MONITORINFOEX)); SafeNativeMethods.GetMonitorInfo(new HandleRef(this, hMonitor), monitorInfo); NativeMethods.RECT workAreaRect = monitorInfo.rcWork; NativeMethods.RECT screenAreaRect = monitorInfo.rcMonitor; deltaX = workAreaRect.left - screenAreaRect.left; deltaY = workAreaRect.top - screenAreaRect.top; } if (transformType == TransformType.WorkAreaToScreenArea) { retPt = new Point(pt.X + deltaX, pt.Y + deltaY); } else { retPt = new Point(pt.X - deltaX, pt.Y - deltaY); } return retPt; }
private static NativeMethods.RECT WorkAreaBoundsForMointor(IntPtr hMonitor) { NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX(); Debug.Assert(hMonitor != IntPtr.Zero); SafeNativeMethods.GetMonitorInfo(new HandleRef(null, hMonitor), monitorInfo); return monitorInfo.rcWork; }
public static extern bool GetMonitorInfo(HandleRef hmonitor, [In, Out] NativeMethods.MONITORINFOEX info);
private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam) { #region // old code commented out by ye.wang 2014-05-04 10:33:18 //// MINMAXINFO structure //NativeMethods.MINMAXINFO minMaxInfo = (NativeMethods.MINMAXINFO)Marshal.PtrToStructure( lParam, typeof( NativeMethods.MINMAXINFO ) ); //// Get the handle of the nearest monitor to the window ////WindowInteropHelper interopHelper = new WindowInteropHelper( this ); //IntPtr hMonitor = NativeMethods.MonitorFromWindow( _wndTarget.GetHandle(), NativeMethods.MONITOR_DEFAULTTONEAREST ); //// Get monitor information //NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX(); //monitorInfo.cbSize = Marshal.SizeOf( monitorInfo ); //NativeMethods.GetMonitorInfo( new HandleRef( this, hMonitor ), monitorInfo ); //// Get HwndSource //HwndSource source = HwndSource.FromHwnd( _wndTarget.GetHandle() ); //if ( source == null ) // // Should never be null // throw new Exception( "Cannot get HwndSource instance." ); //if ( source.CompositionTarget == null ) // // Should never be null // throw new Exception( "Cannot get HwndTarget instance." ); //// Get working area rectangle //NativeMethods.RECT workingArea = monitorInfo.rcWork; //Console.WriteLine( string.Format( "left:{0},top:{1},right:{2},bottom:{3}", monitorInfo.rcWork.Left, // monitorInfo.rcWork.Top, monitorInfo.rcWork.Right, monitorInfo.rcWork.Bottom ) ); //// Get transformation matrix //System.Windows.Media.Matrix matrix = source.CompositionTarget.TransformFromDevice; //// Convert working area rectangle to DPI-independent values //Point convertedSize = // matrix.Transform( new Point( // workingArea.Right - workingArea.Left, // workingArea.Bottom - workingArea.Top // ) ); //Point convertedPosion = // matrix.Transform( new Point( // workingArea.Left, workingArea.Top // ) ); //// Set the maximized size of the window //minMaxInfo.ptMaxSize.X = (int)convertedSize.X+6; //minMaxInfo.ptMaxSize.Y = (int)convertedSize.Y+6; //// Set the position of the maximized window //minMaxInfo.ptMaxPosition.X = (int)convertedPosion.X-WND_BORDER_DROPSHADOW_SIZE; //minMaxInfo.ptMaxPosition.Y = (int)convertedPosion.Y-WND_BORDER_DROPSHADOW_SIZE; //Console.WriteLine( string.Format( "MaxInfo : left:{0},top:{1},right:{2},bottom:{3}", // convertedPosion.X, convertedPosion.Y, convertedSize.X, convertedSize.Y ) ); //Marshal.StructureToPtr( minMaxInfo, lParam, true ); #endregion // // old code NativeMethods.MINMAXINFO mmi = (NativeMethods.MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(NativeMethods.MINMAXINFO)); IntPtr monitor = NativeMethods.MonitorFromWindow(hwnd, NativeMethods.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); NativeMethods.GetMonitorInfo(new HandleRef(this, monitor), monitorInfo); NativeMethods.RECT rcWorkArea = monitorInfo.rcWork; NativeMethods.RECT rcMonitorArea = monitorInfo.rcMonitor; //mmi.ptMaxPosition.X = ( null != this.MaxiX ? this.MaxiX.Value : Math.Abs( rcWorkArea.Left - rcMonitorArea.Left ) ) - WND_BORDER_DROPSHADOW_SIZE; //mmi.ptMaxPosition.Y = ( null != this.MaxiY ? this.MaxiY.Value : Math.Abs( rcWorkArea.Top - rcMonitorArea.Top ) ) - WND_BORDER_DROPSHADOW_SIZE; if (!_bUseCall) { // use field mmi.ptMaxPosition.X = (null != this._maxiX ? this._maxiX.Value : Math.Abs(rcWorkArea.Left - rcMonitorArea.Left)) - WND_BORDER_DROPSHADOW_SIZE; mmi.ptMaxPosition.Y = (null != this._maxiY ? this._maxiY.Value : Math.Abs(rcWorkArea.Top - rcMonitorArea.Top)) - WND_BORDER_DROPSHADOW_SIZE; } else { if (null == this._maxiX_call) { this._maxiX_call = () => null; } if (null == this._maxiY_call) { this._maxiY_call = () => null; } int?ret_x = this._maxiX_call.Invoke(); int?ret_y = this._maxiY_call.Invoke(); mmi.ptMaxPosition.X = (null != ret_x ? ret_x.Value : Math.Abs(rcWorkArea.Left - rcMonitorArea.Left)) - WND_BORDER_DROPSHADOW_SIZE; mmi.ptMaxPosition.Y = (null != ret_y ? ret_y.Value : Math.Abs(rcWorkArea.Top - rcMonitorArea.Top)) - WND_BORDER_DROPSHADOW_SIZE; } mmi.ptMaxSize.X = Math.Abs( Math.Abs(rcWorkArea.Right - rcWorkArea.Left) + WND_BORDER_DROPSHADOW_SIZE - mmi.ptMaxPosition.X); mmi.ptMaxSize.Y = Math.Abs( Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top) + WND_BORDER_DROPSHADOW_SIZE - mmi.ptMaxPosition.Y); mmi.ptMinTrackSize.X = (int)this._wndTarget.MinWidth; mmi.ptMinTrackSize.Y = (int)this._wndTarget.MinHeight; } Marshal.StructureToPtr(mmi, lParam, true); }
// Paramter: Point p should be the most interesting point of a pop up positioning. The top left. // Return the maximum boundingRect for the popup. // If this is not a child-popup // and the Point p passed in is inside of the Work Area then return the monitor work area rect // A tooltip opened above the taskbar will never display over/under the taskbar. // To accomodate this the work area of the screen is returned to allow the pop up to // respect the reserved area of the teskbar. // and the Point p passed in is outside of the work area then return the monitor rect // this can happen If the program is an appbar program (http://msdn.microsoft.com/en-us/library/cc144177(VS.85).aspx) // and the tooltip is in the area removed from the work area. In this case the tooltip can // be placed without regard for the work area bounds. // Else this is the BoundingRect of either the placement target's window or the parent of the popup's window. private Rect GetScreenBounds(Rect boundingBox, Point p) { if (_secHelper.IsChildPopup) { // The "monitor" is the main window for child windows. return _secHelper.GetParentWindowRect(); } NativeMethods.RECT rect = new NativeMethods.RECT(0, 0, 0, 0); NativeMethods.RECT nativeBounds = PointUtil.FromRect(boundingBox); IntPtr monitor = SafeNativeMethods.MonitorFromRect(ref nativeBounds, NativeMethods.MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { NativeMethods.MONITORINFOEX monitorInfo = new NativeMethods.MONITORINFOEX(); monitorInfo.cbSize = Marshal.SizeOf(typeof(NativeMethods.MONITORINFOEX)); SafeNativeMethods.GetMonitorInfo(new HandleRef(null, monitor), monitorInfo); //If this is a pop up for a menu or ToolTip then respect the work area if opening in the work area. if (((this.Child is MenuBase) || (this.Child is ToolTip) || (this.TemplatedParent is MenuItem)) && ((p.X >= monitorInfo.rcWork.left) && (p.X <= monitorInfo.rcWork.right) && (p.Y >= monitorInfo.rcWork.top) && (p.Y <= monitorInfo.rcWork.bottom))) { // Context Menus, MenuItems, and ToolTips shouldn't go over the Taskbar rect = monitorInfo.rcWork; } else { rect = monitorInfo.rcMonitor; } } return PointUtil.ToRect(rect); }