/// <summary> /// Redraws the non client area. /// </summary> /// <param name="invalidateBuffer">if set to <c>true</c> the buffer is invalidated.</param> /// <returns>true if the original painting should be suppressed otherwise false.</returns> private bool NcPaint(bool invalidateBuffer) { if (!IsProcessNcArea) return false; bool result = false; IntPtr hdc = (IntPtr)0; Graphics g = null; Region region = null; IntPtr hrgn = (IntPtr)0; try { // no drawing needed if (_parentForm.MdiParent != null && _parentForm.WindowState == FormWindowState.Maximized) { _currentCacheSize = Size.Empty; return false; } // prepare image bounds Size borderSize = FormExtenders.GetBorderSize(_parentForm); int captionHeight = FormExtenders.GetCaptionHeight(_parentForm); RECT rectScreen = new RECT(); Win32Api.GetWindowRect(_parentForm.Handle, ref rectScreen); Rectangle rectBounds = rectScreen.ToRectangle(); rectBounds.Offset(-rectBounds.X, -rectBounds.Y); // prepare clipping Rectangle rectClip = rectBounds; region = new Region(rectClip); rectClip.Inflate(-borderSize.Width, -borderSize.Height); rectClip.Y += captionHeight; rectClip.Height -= captionHeight; // create graphics handle hdc = Win32Api.GetDCEx(_parentForm.Handle, (IntPtr)0, (DCXFlags.DCX_CACHE | DCXFlags.DCX_CLIPSIBLINGS | DCXFlags.DCX_WINDOW)); g = Graphics.FromHdc(hdc); // Apply clipping region.Exclude(rectClip); hrgn = region.GetHrgn(g); Win32Api.SelectClipRgn(hdc, hrgn); // create new buffered graphics if needed if (_bufferGraphics == null || _currentCacheSize != rectBounds.Size) { if (_bufferGraphics != null) _bufferGraphics.Dispose(); _bufferGraphics = _bufferContext.Allocate(g, new Rectangle(0, 0, rectBounds.Width, rectBounds.Height)); _currentCacheSize = rectBounds.Size; invalidateBuffer = true; } if (invalidateBuffer) { // Create painting meta data for form SkinningFormPaintData paintData = new SkinningFormPaintData(_bufferGraphics.Graphics, rectBounds) { Borders = borderSize, CaptionHeight = captionHeight, Active = _formIsActive, HasMenu = FormExtenders.HasMenu(_parentForm), IconSize = SystemInformation.SmallIconSize, IsSmallCaption = captionHeight == SystemInformation.ToolWindowCaptionHeight, Text = _parentForm.Text }; // create painting meta data for caption buttons if (_captionButtons.Count > 0) { paintData.CaptionButtons = new CaptionButtonPaintData[_captionButtons.Count]; for (int i = 0; i < _captionButtons.Count; i++) { CaptionButton button = _captionButtons[i]; CaptionButtonPaintData buttonData = new CaptionButtonPaintData(_bufferGraphics.Graphics, button.Bounds) { Pressed = button.Pressed, Hovered = button.Hovered, Enabled = button.Enabled, HitTest = button.HitTest }; paintData.CaptionButtons[i] = buttonData; } } // paint result = _manager.CurrentSkin.OnNcPaint(_parentForm, paintData); } // render buffered graphics if (_bufferGraphics != null) _bufferGraphics.Render(g); } catch (Exception) {// error drawing result = false; } // cleanup data if (hdc != (IntPtr)0) { Win32Api.SelectClipRgn(hdc, (IntPtr)0); Win32Api.ReleaseDC(_parentForm.Handle, hdc); } if (region != null && hrgn != (IntPtr)0) region.ReleaseHrgn(hrgn); if (region != null) region.Dispose(); if (g != null) g.Dispose(); return result; }
/// <summary> /// Called when the non client area of the form needs to be painted. /// </summary> /// <param name="form">The form which gets drawn.</param> /// <param name="paintData">The paint data to use for drawing.</param> /// <returns><code>true</code> if the original painting should be suppressed, otherwise <code>false</code></returns> public override bool OnNcPaint(Form form, SkinningFormPaintData paintData) { if (form == null) return false; bool isMaximized = form.WindowState == FormWindowState.Maximized; bool isMinimized = form.WindowState == FormWindowState.Minimized; // prepare bounds Rectangle windowBounds = paintData.Bounds; windowBounds.Location = Point.Empty; Rectangle captionBounds = windowBounds; Size borderSize = paintData.Borders; captionBounds.Height = borderSize.Height + paintData.CaptionHeight; Rectangle textBounds = captionBounds; Rectangle iconBounds = captionBounds; iconBounds.Inflate(-borderSize.Width, 0); iconBounds.Y += borderSize.Height; iconBounds.Height -= borderSize.Height; // Draw Caption bool active = paintData.Active; _formCaption.Draw(paintData.Graphics, captionBounds, active ? 0 : 1); // Paint Icon if (paintData.HasMenu && form.Icon != null) { iconBounds.Size = paintData.IconSize; Icon tmpIcon = new Icon(form.Icon, paintData.IconSize); iconBounds.Y = captionBounds.Y + (captionBounds.Height - iconBounds.Height) / 2; paintData.Graphics.DrawIcon(tmpIcon, iconBounds); textBounds.X = iconBounds.Right; iconBounds.Width -= iconBounds.Right; } // Paint Icons foreach (CaptionButtonPaintData data in paintData.CaptionButtons) { ControlPaintHelper painter = paintData.IsSmallCaption ? _formCaptionButtonSmall : _formCaptionButton; // Get Indices for imagestrip int iconIndex; int backgroundIndex; GetButtonData(data, paintData.Active, out iconIndex, out backgroundIndex); // get imageStrip for button icon ImageStrip iconStrip; switch (data.HitTest) { case HitTest.HTCLOSE: iconStrip = paintData.IsSmallCaption ? _formCloseIconSmall : _formCloseIcon; break; case HitTest.HTMAXBUTTON: if (isMaximized) iconStrip = paintData.IsSmallCaption ? _formRestoreIconSmall : _formRestoreIcon; else iconStrip = paintData.IsSmallCaption ? _formMaximizeIconSmall : _formMaximizeIcon; break; case HitTest.HTMINBUTTON: if (isMinimized) iconStrip = paintData.IsSmallCaption ? _formRestoreIconSmall : _formRestoreIcon; else iconStrip = paintData.IsSmallCaption ? _formMinimizeIconSmall : _formMinimizeIcon; break; default: continue; } // draw background if (backgroundIndex >= 0) painter.Draw(paintData.Graphics, data.Bounds, backgroundIndex); // draw Icon Rectangle b = data.Bounds; b.Y += 1; if (iconIndex >= 0) iconStrip.Draw(paintData.Graphics, iconIndex, b, Rectangle.Empty, DrawingAlign.Center, DrawingAlign.Center); // Ensure textbounds textBounds.Width -= data.Bounds.Width; } // draw text if (!string.IsNullOrEmpty(paintData.Text) && !textBounds.IsEmpty) { TextFormatFlags flags = TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis | TextFormatFlags.PreserveGraphicsClipping; if (_formIsTextCentered) flags = flags | TextFormatFlags.HorizontalCenter; Font font = paintData.IsSmallCaption ? SystemFonts.SmallCaptionFont : SystemFonts.CaptionFont; TextRenderer.DrawText(paintData.Graphics, paintData.Text, font, textBounds, paintData.Active ? _formActiveTitleColor : _formInactiveTitleColor, flags); } // exclude caption area from painting Region region = paintData.Graphics.Clip; region.Exclude(captionBounds); paintData.Graphics.Clip = region; // Paint borders and corners _formBorder.DrawFrame(paintData.Graphics, windowBounds, paintData.Active ? 0 : 1); paintData.Graphics.ResetClip(); return true; }
/// <summary> /// Called when the non client area of the form needs to be painted. /// </summary> /// <param name="form">The form which gets drawn.</param> /// <param name="paintData">The paint data to use for drawing.</param> /// <returns><code>true</code> if the original painting should be suppressed, otherwise <code>false</code></returns> public abstract bool OnNcPaint(Form form, SkinningFormPaintData paintData);