Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Documents/Changelog/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## 2026-11-xx - Build 2611 (V110 Nightly) - November 2026

* Resolved [#2914](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2914), White bar is shown in a `KryptonForm` Sizable without buttons and text
* Resolved [#2862](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2862), Form border resize flicker
* Implemented [#595](https://github.com/Krypton-Suite/Standard-Toolkit/issues/595), Detachable Ribbons - Added ability to detach `KryptonRibbon` into a floating window with `AllowDetach` property, `Detach()` and `Reattach()` methods, and `RibbonDetached`/`RibbonReattached` events. See [Detachable Ribbons Documentation](Detachable-Ribbons-Feature.md) for comprehensive details.
* Implemented [#2898](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2898), `KryptonHScrollBar` & `KryptonVScrollBar` - Part of #2658
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2193,6 +2193,38 @@ protected override bool WindowChromeLeftMouseDown(Point windowPoint)
return ret;
}

/// <inheritdoc />
protected override bool OnWM_NCCALCSIZE(ref Message m)
{
// Does the LParam contain a RECT or an NCCALCSIZE_PARAMS
if (m.WParam != IntPtr.Zero)
{
// Get the border sizing needed around the client area
Padding borders = RealWindowBorders;

// If caption should be hidden, set top border to 0 to prevent white band
if (ShouldHideCaption())
{
borders = new Padding(borders.Left, 0, borders.Right, borders.Bottom);
}

// Extract the Win32 NCCALCSIZE_PARAMS structure from LPARAM
PI.NCCALCSIZE_PARAMS calcsize = (PI.NCCALCSIZE_PARAMS)m.GetLParam(typeof(PI.NCCALCSIZE_PARAMS))!;

// Reduce provided RECT by the borders
calcsize.rectProposed.left += borders.Left;
calcsize.rectProposed.top += borders.Top;
calcsize.rectProposed.right -= borders.Right;
calcsize.rectProposed.bottom -= borders.Bottom;

// Put back the modified structure
Marshal.StructureToPtr(calcsize, m.LParam, false);
}

// Message processed, do not pass onto base class for processing
return true;
}

protected override void OnMove(EventArgs e)
{
base.OnMove(e);
Expand Down Expand Up @@ -2260,6 +2292,30 @@ private void OnFormBorderStyleChanged()
return null;
}

/// <summary>
/// Determines if the caption area should be hidden (no text, no icon, no control box, no visible buttons).
/// </summary>
/// <returns>True if caption should be hidden; otherwise false.</returns>
private bool ShouldHideCaption()
{
// Check if there are any visible buttons
bool hasVisibleButtons = false;
foreach (ButtonSpecView bsv in _buttonManager.ButtonSpecViews)
{
if (bsv.ViewCenter.Visible && bsv.ViewButton.Enabled)
{
hasVisibleButtons = true;
break;
}
}

// Hide caption if no control box, no text, no icon, and no visible buttons
return !ControlBox
&& string.IsNullOrEmpty(GetShortText())
&& GetDefinedIcon() == null
&& !hasVisibleButtons;
}

private void SetHeaderStyle(ViewDrawDocker drawDocker,
PaletteTripleMetricRedirect palette,
HeaderStyle style)
Expand Down Expand Up @@ -2369,15 +2425,29 @@ private bool CheckViewLayout()
}

// Update the heading to enforce a fixed Material-like caption height when Material renderer is active
if (Renderer is RenderMaterial)
bool shouldHideCaption = ShouldHideCaption();

if (shouldHideCaption)
{
const int materialCaptionHeight = 44; // px
_headingFixedSize.FixedSize = new Size(materialCaptionHeight, materialCaptionHeight);
// Hide the caption area when there's nothing to display
_headingFixedSize.FixedSize = Size.Empty;
_headingFixedSize.Visible = false;
}
else
{
Padding windowBorders = RealWindowBorders;
_headingFixedSize.FixedSize = new Size(windowBorders.Top, windowBorders.Top);
// Ensure the heading is visible
_headingFixedSize.Visible = true;

if (Renderer is RenderMaterial)
{
const int materialCaptionHeight = 44; // px
_headingFixedSize.FixedSize = new Size(materialCaptionHeight, materialCaptionHeight);
}
else
{
Padding windowBorders = RealWindowBorders;
_headingFixedSize.FixedSize = new Size(windowBorders.Top, windowBorders.Top);
}
}

// A change in window state since last time requires a layout
Expand Down
49 changes: 49 additions & 0 deletions Source/Krypton Components/TestForm/Bug2914Test.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions Source/Krypton Components/TestForm/Bug2914Test.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TestForm;

public partial class Bug2914Test : KryptonForm
{
public Bug2914Test()
{
InitializeComponent();
}
}
120 changes: 120 additions & 0 deletions Source/Krypton Components/TestForm/Bug2914Test.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
1 change: 1 addition & 0 deletions Source/Krypton Components/TestForm/StartScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private void AddButtons()
CreateButton("Accessibility Test (UIA Providers)", "Comprehensive demo and test for UIA Provider implementation (Issue #762). Tests all 10 controls with accessibility support, organized by category with detailed results.", typeof(AccessibilityTest));
CreateButton("Badge Test", "Comprehensive badge functionality demonstration for KryptonButton and KryptonCheckButton.", typeof(ButtonBadgeTest));
CreateButton("Buttons Test", "All the buttons you want to test.", typeof(ButtonsTest));
CreateButton("Bug 2914 Test", "Tests the fix for 2914.", typeof(Bug2914Test));
CreateButton("BugReportingTool", "Easily report bugs with this tool.", typeof(BugReportingDialogTest));
CreateButton("Code Editor", "Native code editor with syntax highlighting, line numbering, code folding, and auto-completion.", typeof(CodeEditorTest));
CreateButton("Countdown Button", "Comprehensive demonstration of KryptonCountdownButton features with customizable duration, format, and enable-at-zero options.", typeof(CountdownButtonTest));
Expand Down
Loading