/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Size preferredSize = Size.Empty; // We need an owning form to perform calculations if (_ownerForm != null) { // We only have size if custom chrome is being used with composition if (_ownerForm.ApplyCustomChrome && _ownerForm.ApplyComposition) { try { // Create structure that will be populated by call to WM_GETTITLEBARINFOEX PI.TITLEBARINFOEX tbi = new PI.TITLEBARINFOEX(); tbi.cbSize = (uint)Marshal.SizeOf(tbi); // Ask the window for the title bar information PI.SendMessage(_ownerForm.Handle, PI.WM_GETTITLEBARINFOEX, IntPtr.Zero, ref tbi); // Find width of the button rectangle int closeWidth = tbi.rcCloseButton.right - tbi.rcCloseButton.left; int helpWidth = tbi.rcHelpButton.right - tbi.rcHelpButton.left; int minWidth = tbi.rcMinButton.right - tbi.rcMinButton.left; int maxWidth = tbi.rcMaxButton.right - tbi.rcMaxButton.left; int clientWidth = _ownerForm.ClientSize.Width; int clientScreenRight = _ownerForm.RectangleToScreen(_ownerForm.ClientRectangle).Right; int leftMost = clientScreenRight; // Find the left most button edge (start with right side of client area) if ((closeWidth > 0) && (closeWidth < clientWidth)) leftMost = Math.Min(leftMost, tbi.rcCloseButton.left); if ((helpWidth > 0) && (helpWidth < clientWidth)) leftMost = Math.Min(leftMost, tbi.rcHelpButton.left); if ((minWidth > 0) && (minWidth < clientWidth)) leftMost = Math.Min(leftMost, tbi.rcMinButton.left); if ((maxWidth > 0) && (maxWidth < clientWidth)) leftMost = Math.Min(leftMost, tbi.rcMaxButton.left); // Our width is the distance between the left most button edge and the right // side of the client area (this space the buttons are taking up). Plus a small // extra gap between the first button and the caption elements to its left. _width = (clientScreenRight - leftMost) + SPACING_GAP; preferredSize.Width = _width; } catch(ObjectDisposedException) { // Asking for the WM_GETTITLEBARINFOEX can cause exception if the form level // Icon has already been disposed. This happens in rare circumstances. } } } return preferredSize; }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Size preferredSize = Size.Empty; // We need an owning form to perform calculations if (_ownerForm != null) { // We only have size if custom chrome is being used with composition if (_ownerForm.ApplyCustomChrome && _ownerForm.ApplyComposition) { try { // Create structure that will be populated by call to WM_GETTITLEBARINFOEX PI.TITLEBARINFOEX tbi = new PI.TITLEBARINFOEX(); tbi.cbSize = (uint)Marshal.SizeOf(tbi); // Ask the window for the title bar information PI.SendMessage(_ownerForm.Handle, PI.WM_GETTITLEBARINFOEX, IntPtr.Zero, ref tbi); // Find width of the button rectangle int closeWidth = tbi.rcCloseButton.right - tbi.rcCloseButton.left; int helpWidth = tbi.rcHelpButton.right - tbi.rcHelpButton.left; int minWidth = tbi.rcMinButton.right - tbi.rcMinButton.left; int maxWidth = tbi.rcMaxButton.right - tbi.rcMaxButton.left; int clientWidth = _ownerForm.ClientSize.Width; int clientScreenRight = _ownerForm.RectangleToScreen(_ownerForm.ClientRectangle).Right; int leftMost = clientScreenRight; // Find the left most button edge (start with right side of client area) if ((closeWidth > 0) && (closeWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcCloseButton.left); } if ((helpWidth > 0) && (helpWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcHelpButton.left); } if ((minWidth > 0) && (minWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcMinButton.left); } if ((maxWidth > 0) && (maxWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcMaxButton.left); } // Our width is the distance between the left most button edge and the right // side of the client area (this space the buttons are taking up). Plus a small // extra gap between the first button and the caption elements to its left. _width = (clientScreenRight - leftMost) + SPACING_GAP; preferredSize.Width = _width; } catch (ObjectDisposedException) { // Asking for the WM_GETTITLEBARINFOEX can cause exception if the form level // Icon has already been disposed. This happens in rare circumstances. } } } return(preferredSize); }