Skip to content

Commit ed2ac72

Browse files
authored
* Revisit #648 (#2489)
* * Test * * #2480 * * Tidy up * * Fix warnings * Update StartScreen.Designer.cs * * Fixes * * Refinements * * Cleanup * Update KryptonForm.cs * * Fix merge fallout chaos * * Tidy up code * Update KryptonForm.cs * Update KryptonForm.cs * Update KryptonForm.cs * * Cleaned up documentation * * Address feedback * * Address feedback * Update KryptonSystemMenu.cs * * Cleaned up class * * Fixes for feedback * * `ShowOnAltSpace` fixes * * Serialisation * * Serialisation * * More serialisation * Update KryptonSystemMenu.cs * * Removed custom menu item feature * * Fix `TestForm`
1 parent 5da8ad0 commit ed2ac72

37 files changed

+1208
-2329
lines changed

Documents/Changelog/Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
====
44

55
## 2025-11-xx - Build 2511 (V10 - alpha) - November 2025
6+
* Resolved [#2480](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2480). `KryptonForm`'s 'InternalPanel' designer issues
67
* Resolved [#2512](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2512), Added borders with straight corners (`LinearBorder2`) and adjusted the colors in the `KryptonRibbon` in the `Microsoft365` themes. Adjusted the design of the `RibbonQATButton`
78
* Implemented [#2503](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2503), Add the ability to create zip files for binaries
89
* Implemented [#952](https://github.com/Krypton-Suite/Standard-Toolkit/issues/952), Place built NuGet packages into separate directory

Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonForm.cs

Lines changed: 347 additions & 225 deletions
Large diffs are not rendered by default.
Lines changed: 197 additions & 622 deletions
Large diffs are not rendered by default.

Source/Krypton Components/Krypton.Toolkit/Controls Visuals/VisualForm.cs

Lines changed: 93 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,38 @@ protected override void OnShown(EventArgs e)
903903
// */
904904
// base.OnClosing(e);
905905
//}
906+
907+
/// <inheritdoc />
908+
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
909+
{
910+
// Handle basic themed system menu keyboard shortcuts if enabled
911+
// Only handle themed system menu shortcuts if ControlBox is true (same behavior as native system menu)
912+
if (ControlBox && SystemMenuService is { UseSystemMenu: true })
913+
{
914+
// Handle Alt+Space to show the themed system menu (only if enabled)
915+
if (keyData == (Keys.Alt | Keys.Space))
916+
{
917+
// Check if Alt+Space is enabled through the system menu service
918+
if (SystemMenuService.ShowSystemMenuOnAltSpace)
919+
{
920+
ShowSystemMenuAtFormTopLeft();
921+
return true;
922+
}
923+
}
924+
925+
// Handle Alt+F4 for close (let derived classes handle this)
926+
if (keyData == (Keys.Alt | Keys.F4))
927+
{
928+
if (HandleSystemMenuKeyboardShortcut(keyData))
929+
{
930+
return true;
931+
}
932+
}
933+
}
934+
935+
return base.ProcessCmdKey(ref msg, keyData);
936+
}
937+
906938
#endregion
907939

908940
#region Protected Virtual
@@ -1330,7 +1362,7 @@ protected virtual bool OnWM_NCMOUSEMOVE(ref Message m)
13301362
/// <summary>
13311363
/// Process the WM_NCLBUTTONDOWN message when overriding window chrome.
13321364
/// </summary>
1333-
/// <param name="m">A Windows-based message.</param>4
1365+
/// <param name="m">A Windows-based message.</param>
13341366
/// <returns>True if the message was processed; otherwise false.</returns>
13351367
protected virtual bool OnWM_NCLBUTTONDOWN(ref Message m)
13361368
{
@@ -1641,134 +1673,6 @@ protected virtual void WindowChromeMouseLeave() =>
16411673

16421674
#endregion
16431675

1644-
#region Themed System Menu
1645-
/// <summary>
1646-
/// Gets access to the themed system menu for advanced customization.
1647-
/// </summary>
1648-
[Browsable(false)]
1649-
[EditorBrowsable(EditorBrowsableState.Advanced)]
1650-
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1651-
public virtual IKryptonThemedSystemMenu? KryptonSystemMenu => null;
1652-
1653-
/// <summary>
1654-
/// Gets or sets the themed system menu service for managing themed system menu functionality.
1655-
/// </summary>
1656-
[Browsable(false)]
1657-
[EditorBrowsable(EditorBrowsableState.Advanced)]
1658-
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1659-
public virtual KryptonThemedSystemMenuService? SystemMenuService { get; set; }
1660-
1661-
/// <summary>
1662-
/// Determines if the specified screen point is within the title bar area.
1663-
/// </summary>
1664-
/// <param name="screenPoint">The screen coordinates to test.</param>
1665-
/// <returns>True if the point is in the title bar area; otherwise false.</returns>
1666-
protected virtual bool IsInTitleBarArea(Point screenPoint) => false;
1667-
1668-
/// <summary>
1669-
/// Determines if the specified screen point is over the control buttons (min/max/close).
1670-
/// </summary>
1671-
/// <param name="screenPoint">The screen coordinates to test.</param>
1672-
/// <returns>True if the point is over control buttons; otherwise false.</returns>
1673-
protected virtual bool IsOnControlButtons(Point screenPoint) => false;
1674-
1675-
/// <summary>
1676-
/// Shows the themed system menu at the specified screen location.
1677-
/// </summary>
1678-
/// <param name="screenLocation">The screen coordinates where the menu should appear.</param>
1679-
protected virtual void ShowThemedSystemMenu(Point screenLocation) { }
1680-
1681-
/// <summary>
1682-
/// Shows the themed system menu at the form's top-left position.
1683-
/// </summary>
1684-
protected virtual void ShowThemedSystemMenuAtFormTopLeft() { }
1685-
1686-
/// <summary>
1687-
/// Handles keyboard shortcuts for the themed system menu.
1688-
/// </summary>
1689-
/// <param name="keyData">The key data to process.</param>
1690-
/// <returns>True if the shortcut was handled; otherwise false.</returns>
1691-
protected virtual bool HandleThemedSystemMenuKeyboardShortcut(Keys keyData) => false;
1692-
1693-
/// <summary>
1694-
/// Ensures proper form positioning based on StartPosition after custom chrome is applied.
1695-
/// </summary>
1696-
protected virtual void EnsureProperFormPositioning()
1697-
{
1698-
// Get the current screen
1699-
var screen = Screen.FromControl(this);
1700-
var needsRepositioning = false;
1701-
1702-
// Apply custom positioning based on StartPosition
1703-
switch (StartPosition)
1704-
{
1705-
case FormStartPosition.CenterScreen:
1706-
// Check if already centered
1707-
var expectedX = (screen.WorkingArea.Width - Width) / 2;
1708-
var expectedY = (screen.WorkingArea.Height - Height) / 2;
1709-
1710-
// Only reposition if significantly off-center (more than 10 pixels)
1711-
if (Math.Abs(Location.X - expectedX) > 10 || Math.Abs(Location.Y - expectedY) > 10)
1712-
{
1713-
needsRepositioning = true;
1714-
Location = new Point(expectedX, expectedY);
1715-
}
1716-
break;
1717-
1718-
case FormStartPosition.CenterParent:
1719-
// Center relative to parent form
1720-
if (Owner != null)
1721-
{
1722-
var x = Owner.Location.X + (Owner.Width - Width) / 2;
1723-
var y = Owner.Location.Y + (Owner.Height - Height) / 2;
1724-
Location = new Point(x, y);
1725-
}
1726-
break;
1727-
1728-
case FormStartPosition.WindowsDefaultLocation:
1729-
// Let Windows handle the default positioning
1730-
break;
1731-
1732-
case FormStartPosition.WindowsDefaultBounds:
1733-
// Let Windows handle the default positioning and sizing
1734-
break;
1735-
}
1736-
1737-
// If we repositioned, ensure the form is visible on screen
1738-
if (needsRepositioning)
1739-
{
1740-
// Ensure the form is fully visible on screen
1741-
var workingArea = screen.WorkingArea;
1742-
if (Right > workingArea.Right)
1743-
{
1744-
Location = new Point(workingArea.Right - Width, Location.Y);
1745-
}
1746-
if (Bottom > workingArea.Bottom)
1747-
{
1748-
Location = new Point(Location.X, workingArea.Bottom - Height);
1749-
}
1750-
if (Left < workingArea.Left)
1751-
{
1752-
Location = new Point(workingArea.Left, Location.Y);
1753-
}
1754-
if (Top < workingArea.Top)
1755-
{
1756-
Location = new Point(Location.X, workingArea.Top);
1757-
}
1758-
}
1759-
}
1760-
1761-
/// <summary>
1762-
/// Helper method to handle themed system menu shortcuts using the service.
1763-
/// </summary>
1764-
/// <param name="keyData">The key data to process.</param>
1765-
/// <returns>True if the shortcut was handled by the service; otherwise false.</returns>
1766-
protected bool HandleThemedSystemMenuShortcut(Keys keyData)
1767-
{
1768-
return SystemMenuService?.HandleKeyboardShortcut(keyData) ?? false;
1769-
}
1770-
#endregion
1771-
17721676
#region Implementation
17731677
private void OnGlobalPaletteChanged(object? sender, EventArgs e)
17741678
{
@@ -1843,6 +1747,66 @@ private void OnBaseChanged(object? sender, EventArgs e) =>
18431747
#endif
18441748
#endregion
18451749

1750+
#region Themed System Menu
1751+
/// <summary>
1752+
/// Gets access to the system menu for advanced customization.
1753+
/// </summary>
1754+
[Browsable(false)]
1755+
[EditorBrowsable(EditorBrowsableState.Advanced)]
1756+
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1757+
public virtual IKryptonSystemMenu? KryptonSystemMenu => null;
1758+
1759+
/// <summary>
1760+
/// Gets or sets the system menu service for managing themed system menu functionality.
1761+
/// </summary>
1762+
[Browsable(false)]
1763+
[EditorBrowsable(EditorBrowsableState.Advanced)]
1764+
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
1765+
public virtual KryptonSystemMenuService? SystemMenuService { get; set; }
1766+
1767+
/// <summary>
1768+
/// Determines if the specified screen point is within the title bar area.
1769+
/// </summary>
1770+
/// <param name="screenPoint">The screen coordinates to test.</param>
1771+
/// <returns>True if the point is in the title bar area; otherwise false.</returns>
1772+
protected virtual bool IsInTitleBarArea(Point screenPoint) => false;
1773+
1774+
/// <summary>
1775+
/// Determines if the specified screen point is over the control buttons (min/max/close).
1776+
/// </summary>
1777+
/// <param name="screenPoint">The screen coordinates to test.</param>
1778+
/// <returns>True if the point is over control buttons; otherwise false.</returns>
1779+
protected virtual bool IsOnControlButtons(Point screenPoint) => false;
1780+
1781+
/// <summary>
1782+
/// Shows the themed system menu at the specified screen location.
1783+
/// </summary>
1784+
/// <param name="screenLocation">The screen coordinates where the menu should appear.</param>
1785+
protected virtual void ShowSystemMenu(Point screenLocation) { }
1786+
1787+
/// <summary>
1788+
/// Shows the themed system menu at the form's top-left position.
1789+
/// </summary>
1790+
protected virtual void ShowSystemMenuAtFormTopLeft() { }
1791+
1792+
/// <summary>
1793+
/// Handles keyboard shortcuts for the themed system menu.
1794+
/// </summary>
1795+
/// <param name="keyData">The key data to process.</param>
1796+
/// <returns>True if the shortcut was handled; otherwise false.</returns>
1797+
protected virtual bool HandleSystemMenuKeyboardShortcut(Keys keyData) => false;
1798+
1799+
/// <summary>
1800+
/// Helper method to handle themed system menu shortcuts using the service.
1801+
/// </summary>
1802+
/// <param name="keyData">The key data to process.</param>
1803+
/// <returns>True if the shortcut was handled by the service; otherwise false.</returns>
1804+
protected bool HandleSystemMenuShortcut(Keys keyData)
1805+
{
1806+
return SystemMenuService?.HandleKeyboardShortcut(keyData) ?? false;
1807+
}
1808+
#endregion
1809+
18461810
private void UpdateDpiFactors()
18471811
{
18481812
// Do not use the control dpi, as these values are being used to target the screen
@@ -1874,36 +1838,4 @@ private void InitializeComponent()
18741838
Name = "VisualForm";
18751839
ResumeLayout(false);
18761840
}
1877-
1878-
/// <summary>
1879-
/// Processes a command key.
1880-
/// </summary>
1881-
/// <param name="msg">A Message, passed by reference, that represents the window message to process.</param>
1882-
/// <param name="keyData">One of the Keys values that represents the key to process.</param>
1883-
/// <returns>True if the character was processed by the control; otherwise, false.</returns>
1884-
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
1885-
{
1886-
// Handle basic themed system menu keyboard shortcuts if enabled
1887-
// Only handle themed system menu shortcuts if ControlBox is true (same behavior as native system menu)
1888-
if (ControlBox && SystemMenuService is { UseThemedSystemMenu: true })
1889-
{
1890-
// Handle Alt+Space to show the themed system menu
1891-
if (keyData == (Keys.Alt | Keys.Space))
1892-
{
1893-
ShowThemedSystemMenuAtFormTopLeft();
1894-
return true;
1895-
}
1896-
1897-
// Handle Alt+F4 for close (let derived classes handle this)
1898-
if (keyData == (Keys.Alt | Keys.F4))
1899-
{
1900-
if (HandleThemedSystemMenuKeyboardShortcut(keyData))
1901-
{
1902-
return true;
1903-
}
1904-
}
1905-
}
1906-
1907-
return base.ProcessCmdKey(ref msg, keyData);
1908-
}
19091841
}

Source/Krypton Components/Krypton.Toolkit/Controls Visuals/VisualPopupManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,5 +767,6 @@ private void OnCMSClosed(object? sender, ToolStripDropDownClosedEventArgs e)
767767
_cmsFinishDelegate = null;
768768
}
769769
}
770+
770771
#endregion
771772
}

0 commit comments

Comments
 (0)