/// <summary> /// Updates the caption. /// </summary> private void UpdateCaption() { // create buttons if (_captionButtons.Count == 0) { _captionButtons.Add(new CaptionButton(HitTest.HTCLOSE)); if (FormExtenders.IsDrawMaximizeBox(_parentForm)) { var button = new CaptionButton(HitTest.HTMAXBUTTON); // disable button if it is disabled on form. button.Enabled = _parentForm.MaximizeBox; _captionButtons.Add(button); } if (FormExtenders.IsDrawMinimizeBox(_parentForm)) { var button = new CaptionButton(HitTest.HTMINBUTTON); // disable button if it is disabled on form. button.Enabled = _parentForm.MinimizeBox; _captionButtons.Add(button); } // TODO: Add help button if enabled to all skins. // add command handlers foreach (var button in _captionButtons) { button.PropertyChanged += OnCommandButtonPropertyChanged; } } // Calculate Caption Button Bounds var rectScreen = new RECT(); Win32Api.GetWindowRect(_parentForm.Handle, ref rectScreen); var rect = rectScreen.ToRectangle(); var borderSize = FormExtenders.GetBorderSize(_parentForm); rect.Offset(-rect.Left, -rect.Top); var captionButtonSize = FormExtenders.GetCaptionButtonSize(_parentForm); var buttonRect = new Rectangle(rect.Right - borderSize.Width - captionButtonSize.Width, rect.Top + borderSize.Height, captionButtonSize.Width, captionButtonSize.Height); foreach (var button in _captionButtons) { button.Bounds = buttonRect; buttonRect.X -= captionButtonSize.Width; } }
/// <summary> /// Performs the non client HitTest /// </summary> /// <param name="m">The Message</param> /// <returns>true if the orginal handler should be suppressed otherwise false.</returns> private bool NcHitTest(ref Message m) { if (!IsProcessNcArea) { return(false); } Point point = new Point(m.LParam.ToInt32()); Rectangle rectScreen = FormExtenders.GetScreenRect(_parentForm); Rectangle rect = rectScreen; // custom processing if (rect.Contains(point)) { Size borderSize = FormExtenders.GetBorderSize(_parentForm); rect.Inflate(-borderSize.Width, -borderSize.Height); // let form handle hittest itself if we are on borders if (!rect.Contains(point)) { return(false); } Rectangle rectCaption = rect; rectCaption.Height = FormExtenders.GetCaptionHeight(_parentForm); // not in caption -> client if (!rectCaption.Contains(point)) { m.Result = (IntPtr)(int)HitTest.HTCLIENT; return(true); } // on icon? if (FormExtenders.HasMenu(_parentForm)) { Rectangle rectSysMenu = rectCaption; rectSysMenu.Size = SystemInformation.SmallIconSize; if (rectSysMenu.Contains(point)) { m.Result = (IntPtr)(int)HitTest.HTSYSMENU; return(true); } } // on Button? Point pt = new Point(point.X - rectScreen.X, point.Y - rectScreen.Y); CaptionButton sysButton = CommandButtonFromPoint(pt); if (sysButton != null) { m.Result = (IntPtr)sysButton.HitTest; return(true); } // on Caption? m.Result = (IntPtr)(int)HitTest.HTCAPTION; return(true); } m.Result = (IntPtr)(int)HitTest.HTNOWHERE; return(true); }
/// <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); }