private void OnRibbonMdiChildActivate(object sender, EventArgs e) { // Cast to correct type Form topForm = sender as Form; // Unhook from watching any previous mdi child if (_activeMdiChild != null) { _activeMdiChild.SizeChanged -= new EventHandler(OnRibbonMdiChildSizeChanged); } _activeMdiChild = topForm.ActiveMdiChild; // Start watching any new mdi child if (_activeMdiChild != null) { _activeMdiChild.SizeChanged += new EventHandler(OnRibbonMdiChildSizeChanged); } // Update the pendant buttons with reference to new child _buttonSpecClose.MdiChild = _activeMdiChild; _buttonSpecRestore.MdiChild = _activeMdiChild; _buttonSpecMin.MdiChild = _activeMdiChild; _buttonManager.RecreateButtons(); PerformNeedPaint(true); // We never want the mdi child window to have a system menu, we provide the // pendant buttons as part of the ribbon and so replace the need for it. PI.SetMenu(new HandleRef(_ribbon, topForm.Handle), NullHandleRef); if (_activeMdiChild != null) { uint windowStyle = PI.GetWindowLong(_activeMdiChild.Handle, -16); windowStyle |= PI.WS_SYSMENU; PI.SetWindowLong(_activeMdiChild.Handle, -16, windowStyle); } }
/// <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); }
private void RenderOnComposition(RenderContext context) { // Convert the clipping rectangle from floating to int version RectangleF rectClipF = context.Graphics.ClipBounds; Rectangle rectClip = new Rectangle((int)rectClipF.X, (int)rectClipF.Y, (int)rectClipF.Width, (int)rectClipF.Height); // No point drawing unless some of the client fits into the clipping area if (rectClip.IntersectsWith(ClientRectangle)) { // Get the hDC for the graphics instance and create a memory DC IntPtr gDC = context.Graphics.GetHdc(); IntPtr mDC = PI.CreateCompatibleDC(gDC); PI.BITMAPINFO bmi = new PI.BITMAPINFO(); bmi.biSize = Marshal.SizeOf(bmi); bmi.biWidth = ClientWidth; bmi.biHeight = -ClientHeight; bmi.biCompression = 0; bmi.biBitCount = 32; bmi.biPlanes = 1; // Create a device independant bitmp and select into the memory DC IntPtr hDIB = PI.CreateDIBSection(gDC, bmi, 0, 0, IntPtr.Zero, 0); PI.SelectObject(mDC, hDIB); // To call the renderer we need to convert from Win32 HDC to Graphics object using (Graphics bitmapG = Graphics.FromHdc(mDC)) { Rectangle renderClientRect = new Rectangle(0, 0, ClientWidth, ClientHeight); // Create new render context that uses the bitmap graphics instance using (RenderContext bitmapContext = new RenderContext(context.Control, bitmapG, renderClientRect, context.Renderer)) { // Finally we get the renderer to draw the background for the bitmap _mementoBack = context.Renderer.RenderRibbon.DrawRibbonTabContextTitle(_ribbon.RibbonShape, bitmapContext, renderClientRect, _ribbon.StateCommon.RibbonGeneral, this, _mementoBack); } } // Select the font for use when drawing IntPtr hFont = _contentProvider.GetContentShortTextFont(State).ToHfont(); PI.SelectObject(mDC, hFont); // Get renderer for the correct state VisualStyleRenderer renderer = new VisualStyleRenderer(VisualStyleElement.Window.Caption.Active); // Create structures needed for theme drawing call PI.RECT textBounds = new PI.RECT(); textBounds.left = TEXT_SIDE_GAP_COMPOSITION; textBounds.top = 0; textBounds.right = ClientWidth - (TEXT_SIDE_GAP_COMPOSITION * 2); textBounds.bottom = ClientHeight; PI.DTTOPTS dttOpts = new PI.DTTOPTS(); dttOpts.dwSize = Marshal.SizeOf(typeof(PI.DTTOPTS)); dttOpts.dwFlags = PI.DTT_COMPOSITED | PI.DTT_GLOWSIZE | PI.DTT_TEXTCOLOR; dttOpts.crText = ColorTranslator.ToWin32(SystemColors.ActiveCaptionText); dttOpts.iGlowSize = (_ribbon.Enabled ? 12 : 2); // Always draw text centered TextFormatFlags textFormat = TextFormatFlags.SingleLine | TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis; // Perform actual drawing PI.DrawThemeTextEx(renderer.Handle, mDC, 0, 0, GetShortText(), -1, (int)textFormat, ref textBounds, ref dttOpts); // Copy to foreground PI.BitBlt(gDC, ClientLocation.X, ClientLocation.Y, ClientWidth, ClientHeight, mDC, 0, 0, 0x00CC0020); // Dispose of allocated objects PI.DeleteObject(hFont); PI.DeleteObject(hDIB); PI.DeleteDC(mDC); // Must remember to release the hDC context.Graphics.ReleaseHdc(gDC); } }