/// <summary> /// Returns monitor in witch control is placed /// </summary> /// <param name="control">Control</param> /// <returns>Workarea in witch control is placed</returns> public static Rect GetControlMonitor(FrameworkElement control) { var tabItemPos = control.PointToScreen(new Point(0, 0)); var tabItemRect = new RECT(); tabItemRect.left = (int)tabItemPos.X; tabItemRect.top = (int)tabItemPos.Y; tabItemRect.right = (int)tabItemPos.X + (int)control.ActualWidth; tabItemRect.bottom = (int)tabItemPos.Y + (int)control.ActualHeight; const uint MONITOR_DEFAULTTONEAREST = 0x00000002; var monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITOR_DEFAULTTONEAREST); if (monitor != IntPtr.Zero) { var monitorInfo = new MONITORINFO(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); NativeMethods.GetMonitorInfo(monitor, monitorInfo); return new Rect(monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top); } return new Rect(); }
/// <summary> /// Implements custom placement for ribbon popup /// </summary> /// <param name="popupsize"></param> /// <param name="targetsize"></param> /// <param name="offset"></param> /// <returns></returns> private CustomPopupPlacement[] CustomPopupPlacementMethod(Size popupsize, Size targetsize, Point offset) { if (this.DropDownPopup == null || this.SelectedTabItem == null) { return null; } // Get current workarea var tabItemPos = this.SelectedTabItem.PointToScreen(new Point(0, 0)); var tabItemRect = new RECT { left = (int)tabItemPos.X, top = (int)tabItemPos.Y, right = (int)tabItemPos.X + (int)this.SelectedTabItem.ActualWidth, bottom = (int)tabItemPos.Y + (int)this.SelectedTabItem.ActualHeight }; const uint MONITOR_DEFAULTTONEAREST = 0x00000002; var monitor = NativeMethods.MonitorFromRect(ref tabItemRect, MONITOR_DEFAULTTONEAREST); if (monitor == IntPtr.Zero) { return null; } var monitorInfo = new MONITORINFO(); monitorInfo.cbSize = Marshal.SizeOf(monitorInfo); UnsafeNativeMethods.GetMonitorInfo(monitor, monitorInfo); var startPoint = this.PointToScreen(new Point(0, 0)); if (this.FlowDirection == FlowDirection.RightToLeft) { startPoint.X -= this.ActualWidth; } var inWindowRibbonWidth = monitorInfo.rcWork.right - Math.Max(monitorInfo.rcWork.left, startPoint.X); var actualWidth = this.ActualWidth; if (startPoint.X < monitorInfo.rcWork.left) { actualWidth -= monitorInfo.rcWork.left - startPoint.X; startPoint.X = monitorInfo.rcWork.left; } // Set width and prevent negative values this.DropDownPopup.Width = Math.Max(0, Math.Min(actualWidth, inWindowRibbonWidth)); return new[] { new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X + offset.X, targetsize.Height + offset.Y), PopupPrimaryAxis.Vertical), new CustomPopupPlacement(new Point(startPoint.X - tabItemPos.X + offset.X, -1 * (targetsize.Height + offset.Y + ((ScrollViewer)this.SelectedContent).ActualHeight)), PopupPrimaryAxis.Vertical) }; }
internal static extern IntPtr MonitorFromPoint(POINT pt, MONITORINFO.MonitorOptions dwFlags);
private MINMAXINFO GetMinMaxInfo(IntPtr hwnd, MINMAXINFO mmi) { // Adjust the maximized size and position to fit the work area of the correct monitor var monitor = UnsafeNativeMethods.MonitorFromWindow(hwnd, Constants.MONITOR_DEFAULTTONEAREST); if (monitor == IntPtr.Zero) { return mmi; } var monitorInfo = new MONITORINFO(); UnsafeNativeMethods.GetMonitorInfo(monitor, monitorInfo); var rcWorkArea = monitorInfo.rcWork; var rcMonitorArea = monitorInfo.rcMonitor; Debug.WriteLine("Monitor-Info"); Debug.WriteLine(string.Format("Work: {0}", rcWorkArea)); Debug.WriteLine(string.Format("Mon : {0}", rcMonitorArea)); Debug.WriteLine(string.Format("Before: {0}", mmi)); mmi.ptMaxPosition.X = rcWorkArea.left; mmi.ptMaxPosition.Y = rcWorkArea.top; var ignoreTaskBar = this.IgnoreTaskBar(); var x = ignoreTaskBar ? monitorInfo.rcMonitor.left : monitorInfo.rcWork.left; var y = ignoreTaskBar ? monitorInfo.rcMonitor.top : monitorInfo.rcWork.top; mmi.ptMaxSize.X = ignoreTaskBar ? Math.Abs(monitorInfo.rcMonitor.right - x) : Math.Abs(monitorInfo.rcWork.right - x); mmi.ptMaxSize.Y = ignoreTaskBar ? Math.Abs(monitorInfo.rcMonitor.bottom - y) : Math.Abs(monitorInfo.rcWork.bottom - y); if (!ignoreTaskBar) { mmi.ptMaxTrackSize.X = mmi.ptMaxSize.X; mmi.ptMaxTrackSize.Y = mmi.ptMaxSize.Y; mmi = AdjustWorkingAreaForAutoHide(monitor, mmi); } Debug.WriteLine(string.Format("After: {0}", mmi)); return mmi; }