diff --git a/Documents/Changelog/Changelog.md b/Documents/Changelog/Changelog.md
index f951d089b..0557ed46e 100644
--- a/Documents/Changelog/Changelog.md
+++ b/Documents/Changelog/Changelog.md
@@ -4,6 +4,8 @@
## 2026-11-xx - Build 2611 (V110 Nightly) - November 2026
+* Resolved/Implemented [#2844](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2844), Touchscreen High DPI scaling
+* Implemented [#2808](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2808), Move `KryptonToastNotification` feature to `Krypton.Utilities`
* Implemented [#2572](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2572), Autocomplete control/menu
- To use, you will need to download the `Krypton.Standard.Toolkit` NuGet package, as this control is part of the `Krypton.Utilities` assembly.
* Implemented [#2812](https://github.com/Krypton-Suite/Standard-Toolkit/issues/2812), Code Editor Control
diff --git a/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonManager.cs b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonManager.cs
index 38271bd39..4ec2f1113 100644
--- a/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonManager.cs
+++ b/Source/Krypton Components/Krypton.Toolkit/Controls Toolkit/KryptonManager.cs
@@ -37,6 +37,8 @@ public sealed class KryptonManager : Component
private static System.Threading.Timer? _touchscreenDetectionTimer;
private static bool _lastDetectedTouchscreenState = false;
private static Font? _baseFont;
+ private static float _cachedDpiX = 0f;
+ private static float _cachedDpiY = 0f;
// Initialize the default modes
@@ -1615,4 +1617,390 @@ private static void OnGlobalTouchscreenSupportChanged(EventArgs e)
#endregion
+ #region DPI-Aware Helper Methods
+
+ ///
+ /// Gets the current DPI scaling factor for the X axis (horizontal).
+ /// Returns 1.0 for 96 DPI (100% scaling), 1.25 for 120 DPI (125% scaling), etc.
+ /// Uses the primary monitor's DPI. For per-monitor DPI awareness, use the overload that accepts a window handle.
+ ///
+ /// The DPI scaling factor for the X axis.
+ public static float GetDpiFactorX()
+ {
+ if (_cachedDpiX <= 0.1f)
+ {
+ var screenDc = PI.GetDC(IntPtr.Zero);
+
+ if (screenDc != IntPtr.Zero)
+ {
+ _cachedDpiX = PI.GetDeviceCaps(screenDc, PI.DeviceCap.LOGPIXELSX) / 96f;
+
+ PI.ReleaseDC(IntPtr.Zero, screenDc);
+ }
+ else
+ {
+ using (Graphics gfx = Graphics.FromHwnd(IntPtr.Zero))
+ {
+ _cachedDpiX = gfx.DpiX / 96f;
+ }
+ }
+ }
+
+ return _cachedDpiX;
+ }
+
+ ///
+ /// Gets the DPI scaling factor for the X axis (horizontal) for a specific window.
+ /// This method supports per-monitor DPI awareness by using the window's monitor DPI.
+ /// Returns 1.0 for 96 DPI (100% scaling), 1.25 for 120 DPI (125% scaling), etc.
+ ///
+ /// Window handle to get the DPI for. If IntPtr.Zero, falls back to primary monitor DPI.
+ /// The DPI scaling factor for the X axis.
+ public static float GetDpiFactorX(IntPtr hWnd)
+ {
+ if (hWnd == IntPtr.Zero)
+ {
+ return GetDpiFactorX();
+ }
+
+ // Try to use GetDpiForWindow for per-monitor DPI awareness (Windows 10 version 1607+)
+ try
+ {
+ uint dpi = PI.GetDpiForWindow(hWnd);
+
+ if (dpi > 0)
+ {
+ return dpi / 96f;
+ }
+ }
+ catch
+ {
+ // GetDpiForWindow may not be available on older Windows versions
+ }
+
+ // Fallback to window's Graphics DPI
+ try
+ {
+ using (Graphics graphics = Graphics.FromHwnd(hWnd))
+ {
+ return graphics.DpiX / 96f;
+ }
+ }
+ catch
+ {
+ // Final fallback to primary monitor
+ return GetDpiFactorX();
+ }
+ }
+
+ ///
+ /// Gets the current DPI scaling factor for the Y axis (vertical).
+ /// Returns 1.0 for 96 DPI (100% scaling), 1.25 for 120 DPI (125% scaling), etc.
+ /// Uses the primary monitor's DPI. For per-monitor DPI awareness, use the overload that accepts a window handle.
+ ///
+ /// The DPI scaling factor for the Y axis.
+ public static float GetDpiFactorY()
+ {
+ if (_cachedDpiY <= 0.1f)
+ {
+ var screenDc = PI.GetDC(IntPtr.Zero);
+ if (screenDc != IntPtr.Zero)
+ {
+ _cachedDpiY = PI.GetDeviceCaps(screenDc, PI.DeviceCap.LOGPIXELSY) / 96f;
+ PI.ReleaseDC(IntPtr.Zero, screenDc);
+ }
+ else
+ {
+ // Fallback method
+ using Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
+ _cachedDpiY = graphics.DpiY / 96f;
+ }
+ }
+
+ return _cachedDpiY;
+ }
+
+ ///
+ /// Gets the DPI scaling factor for the Y axis (vertical) for a specific window.
+ /// This method supports per-monitor DPI awareness by using the window's monitor DPI.
+ /// Returns 1.0 for 96 DPI (100% scaling), 1.25 for 120 DPI (125% scaling), etc.
+ ///
+ /// Window handle to get the DPI for. If IntPtr.Zero, falls back to primary monitor DPI.
+ /// The DPI scaling factor for the Y axis.
+ public static float GetDpiFactorY(IntPtr hWnd)
+ {
+ if (hWnd == IntPtr.Zero)
+ {
+ return GetDpiFactorY();
+ }
+
+ // Try to use GetDpiForWindow for per-monitor DPI awareness (Windows 10 version 1607+)
+ try
+ {
+ uint dpi = PI.GetDpiForWindow(hWnd);
+ if (dpi > 0)
+ {
+ return dpi / 96f;
+ }
+ }
+ catch
+ {
+ // GetDpiForWindow may not be available on older Windows versions
+ }
+
+ // Fallback to window's Graphics DPI
+ try
+ {
+ using Graphics graphics = Graphics.FromHwnd(hWnd);
+ return graphics.DpiY / 96f;
+ }
+ catch
+ {
+ // Final fallback to primary monitor
+ return GetDpiFactorY();
+ }
+ }
+
+ ///
+ /// Gets the current DPI scaling factor (average of X and Y axes).
+ /// Useful when uniform scaling is assumed.
+ /// Uses the primary monitor's DPI. For per-monitor DPI awareness, use the overload that accepts a window handle.
+ ///
+ /// The average DPI scaling factor.
+ public static float GetDpiFactor() => (GetDpiFactorX() + GetDpiFactorY()) / 2f;
+
+ ///
+ /// Gets the DPI scaling factor (average of X and Y axes) for a specific window.
+ /// This method supports per-monitor DPI awareness by using the window's monitor DPI.
+ ///
+ /// Window handle to get the DPI for. If IntPtr.Zero, falls back to primary monitor DPI.
+ /// The average DPI scaling factor.
+ public static float GetDpiFactor(IntPtr hWnd) => (GetDpiFactorX(hWnd) + GetDpiFactorY(hWnd)) / 2f;
+
+ ///
+ /// Gets the combined scaling factor (DPI × Touchscreen) for the X axis.
+ /// This represents the total scaling that will be applied to control sizes.
+ /// Uses the primary monitor's DPI. For per-monitor DPI awareness, use the overload that accepts a window handle.
+ ///
+ /// The combined scaling factor for the X axis.
+ public static float GetCombinedScaleFactorX()
+ {
+ var dpiFactor = GetDpiFactorX();
+ var touchscreenFactor = TouchscreenScaleFactor;
+ return dpiFactor * touchscreenFactor;
+ }
+
+ ///
+ /// Gets the combined scaling factor (DPI × Touchscreen) for the X axis for a specific window.
+ /// This method supports per-monitor DPI awareness, which is important for touchscreen support on high DPI displays.
+ /// This represents the total scaling that will be applied to control sizes.
+ ///
+ /// Window handle to get the DPI for. If IntPtr.Zero, falls back to primary monitor DPI.
+ /// The combined scaling factor for the X axis.
+ public static float GetCombinedScaleFactorX(IntPtr hWnd)
+ {
+ var dpiFactor = GetDpiFactorX(hWnd);
+ var touchscreenFactor = TouchscreenScaleFactor;
+ return dpiFactor * touchscreenFactor;
+ }
+
+ ///
+ /// Gets the combined scaling factor (DPI × Touchscreen) for the Y axis.
+ /// This represents the total scaling that will be applied to control sizes.
+ /// Uses the primary monitor's DPI. For per-monitor DPI awareness, use the overload that accepts a window handle.
+ ///
+ /// The combined scaling factor for the Y axis.
+ public static float GetCombinedScaleFactorY()
+ {
+ var dpiFactor = GetDpiFactorY();
+ var touchscreenFactor = TouchscreenScaleFactor;
+ return dpiFactor * touchscreenFactor;
+ }
+
+ ///
+ /// Gets the combined scaling factor (DPI × Touchscreen) for the Y axis for a specific window.
+ /// This method supports per-monitor DPI awareness, which is important for touchscreen support on high DPI displays.
+ /// This represents the total scaling that will be applied to control sizes.
+ ///
+ /// Window handle to get the DPI for. If IntPtr.Zero, falls back to primary monitor DPI.
+ /// The combined scaling factor for the Y axis.
+ public static float GetCombinedScaleFactorY(IntPtr hWnd)
+ {
+ var dpiFactor = GetDpiFactorY(hWnd);
+ var touchscreenFactor = TouchscreenScaleFactor;
+ return dpiFactor * touchscreenFactor;
+ }
+
+ ///
+ /// Gets the combined scaling factor (DPI × Touchscreen) as an average.
+ /// Useful when uniform scaling is assumed.
+ /// Uses the primary monitor's DPI. For per-monitor DPI awareness, use the overload that accepts a window handle.
+ ///
+ /// The average combined scaling factor.
+ public static float GetCombinedScaleFactor() => (GetCombinedScaleFactorX() + GetCombinedScaleFactorY()) / 2f;
+
+ ///
+ /// Gets the combined scaling factor (DPI × Touchscreen) as an average for a specific window.
+ /// This method supports per-monitor DPI awareness, which is important for touchscreen support on high DPI displays.
+ /// Useful when uniform scaling is assumed.
+ ///
+ /// Window handle to get the DPI for. If IntPtr.Zero, falls back to primary monitor DPI.
+ /// The average combined scaling factor.
+ public static float GetCombinedScaleFactor(IntPtr hWnd) => (GetCombinedScaleFactorX(hWnd) + GetCombinedScaleFactorY(hWnd)) / 2f;
+
+ ///
+ /// Scales a single value by the current DPI factor.
+ ///
+ /// The value to scale.
+ /// The scaled value.
+ public static int ScaleValueByDpi(int value) => (int)Math.Round(value * GetDpiFactor());
+
+ ///
+ /// Scales a single value by the current DPI factor.
+ ///
+ /// The value to scale.
+ /// The scaled value.
+ public static float ScaleValueByDpi(float value) => value * GetDpiFactor();
+
+ ///
+ /// Scales a single value by the combined DPI and touchscreen factor.
+ ///
+ /// The value to scale.
+ /// The scaled value.
+ public static int ScaleValueByDpiAndTouchscreen(int value) => (int)Math.Round(value * GetCombinedScaleFactor());
+
+ ///
+ /// Scales a single value by the combined DPI and touchscreen factor.
+ ///
+ /// The value to scale.
+ /// The scaled value.
+ public static float ScaleValueByDpiAndTouchscreen(float value) => value * GetCombinedScaleFactor();
+
+ ///
+ /// Scales a Size by the current DPI factors (X and Y separately).
+ ///
+ /// The size to scale.
+ /// The scaled size.
+ public static Size ScaleSizeByDpi(Size size) => new Size(
+ (int)Math.Round(size.Width * GetDpiFactorX()),
+ (int)Math.Round(size.Height * GetDpiFactorY()));
+
+ ///
+ /// Scales a SizeF by the current DPI factors (X and Y separately).
+ ///
+ /// The size to scale.
+ /// The scaled size.
+ public static SizeF ScaleSizeByDpi(SizeF size) => new SizeF(
+ size.Width * GetDpiFactorX(),
+ size.Height * GetDpiFactorY());
+
+ ///
+ /// Scales a Size by the combined DPI and touchscreen factors (X and Y separately).
+ ///
+ /// The size to scale.
+ /// The scaled size.
+ public static Size ScaleSizeByDpiAndTouchscreen(Size size) => new Size(
+ (int)Math.Round(size.Width * GetCombinedScaleFactorX()),
+ (int)Math.Round(size.Height * GetCombinedScaleFactorY()));
+
+ ///
+ /// Scales a SizeF by the combined DPI and touchscreen factors (X and Y separately).
+ ///
+ /// The size to scale.
+ /// The scaled size.
+ public static SizeF ScaleSizeByDpiAndTouchscreen(SizeF size) => new SizeF(
+ size.Width * GetCombinedScaleFactorX(),
+ size.Height * GetCombinedScaleFactorY());
+
+ ///
+ /// Scales a Point by the current DPI factors (X and Y separately).
+ ///
+ /// The point to scale.
+ /// The scaled point.
+ public static Point ScalePointByDpi(Point point) => new Point(
+ (int)Math.Round(point.X * GetDpiFactorX()),
+ (int)Math.Round(point.Y * GetDpiFactorY()));
+
+ ///
+ /// Scales a PointF by the current DPI factors (X and Y separately).
+ ///
+ /// The point to scale.
+ /// The scaled point.
+ public static PointF ScalePointByDpi(PointF point) => new PointF(
+ point.X * GetDpiFactorX(),
+ point.Y * GetDpiFactorY());
+
+ ///
+ /// Scales a Point by the combined DPI and touchscreen factors (X and Y separately).
+ ///
+ /// The point to scale.
+ /// The scaled point.
+ public static Point ScalePointByDpiAndTouchscreen(Point point) => new Point(
+ (int)Math.Round(point.X * GetCombinedScaleFactorX()),
+ (int)Math.Round(point.Y * GetCombinedScaleFactorY()));
+
+ ///
+ /// Scales a PointF by the combined DPI and touchscreen factors (X and Y separately).
+ ///
+ /// The point to scale.
+ /// The scaled point.
+ public static PointF ScalePointByDpiAndTouchscreen(PointF point) => new PointF(
+ point.X * GetCombinedScaleFactorX(),
+ point.Y * GetCombinedScaleFactorY());
+
+ ///
+ /// Scales a Rectangle by the current DPI factors (X and Y separately).
+ ///
+ /// The rectangle to scale.
+ /// The scaled rectangle.
+ public static Rectangle ScaleRectangleByDpi(Rectangle rect) => new Rectangle(
+ (int)Math.Round(rect.X * GetDpiFactorX()),
+ (int)Math.Round(rect.Y * GetDpiFactorY()),
+ (int)Math.Round(rect.Width * GetDpiFactorX()),
+ (int)Math.Round(rect.Height * GetDpiFactorY()));
+
+ ///
+ /// Scales a RectangleF by the current DPI factors (X and Y separately).
+ ///
+ /// The rectangle to scale.
+ /// The scaled rectangle.
+ public static RectangleF ScaleRectangleByDpi(RectangleF rect) => new RectangleF(
+ rect.X * GetDpiFactorX(),
+ rect.Y * GetDpiFactorY(),
+ rect.Width * GetDpiFactorX(),
+ rect.Height * GetDpiFactorY());
+
+ ///
+ /// Scales a Rectangle by the combined DPI and touchscreen factors (X and Y separately).
+ ///
+ /// The rectangle to scale.
+ /// The scaled rectangle.
+ public static Rectangle ScaleRectangleByDpiAndTouchscreen(Rectangle rect) => new Rectangle(
+ (int)Math.Round(rect.X * GetCombinedScaleFactorX()),
+ (int)Math.Round(rect.Y * GetCombinedScaleFactorY()),
+ (int)Math.Round(rect.Width * GetCombinedScaleFactorX()),
+ (int)Math.Round(rect.Height * GetCombinedScaleFactorY()));
+
+ ///
+ /// Scales a RectangleF by the combined DPI and touchscreen factors (X and Y separately).
+ ///
+ /// The rectangle to scale.
+ /// The scaled rectangle.
+ public static RectangleF ScaleRectangleByDpiAndTouchscreen(RectangleF rect) => new RectangleF(
+ rect.X * GetCombinedScaleFactorX(),
+ rect.Y * GetCombinedScaleFactorY(),
+ rect.Width * GetCombinedScaleFactorX(),
+ rect.Height * GetCombinedScaleFactorY());
+
+ ///
+ /// Invalidates the cached DPI factors, forcing them to be recalculated on the next access.
+ /// Call this method when the DPI changes (e.g., when the window is moved to a different monitor).
+ ///
+ public static void InvalidateDpiCache()
+ {
+ _cachedDpiX = 0f;
+ _cachedDpiY = 0f;
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/Source/Krypton Components/Krypton.Toolkit/Controls Visuals/VisualForm.cs b/Source/Krypton Components/Krypton.Toolkit/Controls Visuals/VisualForm.cs
index d4504bb56..fd6720b1d 100644
--- a/Source/Krypton Components/Krypton.Toolkit/Controls Visuals/VisualForm.cs
+++ b/Source/Krypton Components/Krypton.Toolkit/Controls Visuals/VisualForm.cs
@@ -1931,6 +1931,45 @@ private void OnJumpListChanged()
private void UpdateDpiFactors()
{
+ // Invalidate the global DPI cache to ensure fresh values are calculated
+ KryptonManager.InvalidateDpiCache();
+
+ // Use per-monitor DPI for proper high DPI and touchscreen scaling support
+ IntPtr hWnd = IsHandleCreated ? Handle : IntPtr.Zero;
+
+ if (hWnd != IntPtr.Zero)
+ {
+ try
+ {
+ // Try to use GetDpiForWindow for per-monitor DPI awareness (Windows 10 version 1607+)
+ uint dpi = PI.GetDpiForWindow(hWnd);
+ if (dpi > 0)
+ {
+ FactorDpiX = dpi / 96f;
+ FactorDpiY = dpi / 96f;
+ return;
+ }
+ }
+ catch
+ {
+ // GetDpiForWindow may not be available on older Windows versions
+ }
+
+ // Fallback to window's Graphics DPI
+ try
+ {
+ using Graphics graphics = Graphics.FromHwnd(hWnd);
+ FactorDpiX = graphics.DpiX / 96f;
+ FactorDpiY = graphics.DpiY / 96f;
+ return;
+ }
+ catch
+ {
+ // Continue to primary monitor fallback
+ }
+ }
+
+ // Fallback
// Do not use the control dpi, as these values are being used to target the screen
IntPtr screenDc = PI.GetDC(IntPtr.Zero);
if (screenDc != IntPtr.Zero)
diff --git a/Source/Krypton Components/Krypton.Toolkit/View Base/ViewBase.cs b/Source/Krypton Components/Krypton.Toolkit/View Base/ViewBase.cs
index 1690ab4c3..214b5f32a 100644
--- a/Source/Krypton Components/Krypton.Toolkit/View Base/ViewBase.cs
+++ b/Source/Krypton Components/Krypton.Toolkit/View Base/ViewBase.cs
@@ -240,6 +240,53 @@ public float FactorDpiX
private void InitialiseFactors()
{
+ // Try to get per-monitor DPI from the owning control for proper high DPI support
+ Control? owningControl = OwningControl;
+ IntPtr hWnd = IntPtr.Zero;
+
+ if (owningControl != null && owningControl.IsHandleCreated)
+ {
+ hWnd = owningControl.Handle;
+ }
+ else if (Component is Control componentControl && componentControl.IsHandleCreated)
+ {
+ hWnd = componentControl.Handle;
+ }
+
+ // Use per-monitor DPI if we have a window handle (supports high DPI and touchscreen scaling)
+ if (hWnd != IntPtr.Zero)
+ {
+ try
+ {
+ // Try to use GetDpiForWindow for per-monitor DPI awareness (Windows 10 version 1607+)
+ uint dpi = PI.GetDpiForWindow(hWnd);
+ if (dpi > 0)
+ {
+ _factorDpiX = dpi / 96f;
+ _factorDpiY = dpi / 96f;
+ return;
+ }
+ }
+ catch
+ {
+ // GetDpiForWindow may not be available on older Windows versions
+ }
+
+ // Fallback to window's Graphics DPI
+ try
+ {
+ using Graphics graphics = Graphics.FromHwnd(hWnd);
+ _factorDpiX = graphics.DpiX / 96f;
+ _factorDpiY = graphics.DpiY / 96f;
+ return;
+ }
+ catch
+ {
+ // Continue to primary monitor fallback
+ }
+ }
+
+ // Fallback
// This does mean that the app will not change it's dpi awareness until restarted !
// Do not use the control dpi, as these values are being used to target the screen
var screenDc = PI.GetDC(IntPtr.Zero);
@@ -274,6 +321,16 @@ public float FactorDpiY
}
}
+ ///
+ /// Invalidates the cached DPI factors, forcing them to be recalculated on the next access.
+ /// Call this method when the DPI changes (e.g., when the window is moved to a different monitor).
+ ///
+ public void InvalidateDpiFactors()
+ {
+ _factorDpiX = 0f;
+ _factorDpiY = 0f;
+ }
+
#endregion
#region Component
diff --git a/Source/Krypton Components/TestForm/StartScreen.cs b/Source/Krypton Components/TestForm/StartScreen.cs
index d15894408..5c31e6fd6 100644
--- a/Source/Krypton Components/TestForm/StartScreen.cs
+++ b/Source/Krypton Components/TestForm/StartScreen.cs
@@ -84,6 +84,7 @@ private void AddButtons()
CreateButton("Taskbar Overlay Icon Test", "Comprehensive demonstration of taskbar overlay icons on KryptonForm with configurable icons, descriptions, and interactive examples.", typeof(TaskbarOverlayIconTest));
CreateButton("Theme Controls", string.Empty, typeof(ThemeControlExamples));
CreateButton("TextBox Validating Test", "Tests fix for Validating event duplication bug #2801", typeof(KryptonTextBoxValidatingTest));
+ CreateButton("Touchscreen + High DPI Demo", "Comprehensive demonstration of touchscreen support with per-monitor high DPI scaling (Issue #2844).", typeof(TouchscreenHighDpiDemo));
CreateButton("RichTextBox Formatting Test", "Tests fix for RichTextBox formatting preservation when palette changes (Issue #2832)", typeof(RichTextBoxFormattingTest));
CreateButton("RTL Layout Test", "Test for RTL compliance", typeof(RTLFormBorderTest));
CreateButton("Toast", "For breakfast....?", typeof(ToastNotificationTestChoice));
diff --git a/Source/Krypton Components/TestForm/TouchscreenHighDpiDemo.Designer.cs b/Source/Krypton Components/TestForm/TouchscreenHighDpiDemo.Designer.cs
new file mode 100644
index 000000000..ac5b75c11
--- /dev/null
+++ b/Source/Krypton Components/TestForm/TouchscreenHighDpiDemo.Designer.cs
@@ -0,0 +1,676 @@
+namespace TestForm
+{
+ partial class TouchscreenHighDpiDemo
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ _dpiMonitorTimer?.Stop();
+ _dpiMonitorTimer?.Dispose();
+ KryptonManager.GlobalTouchscreenSupportChanged -= OnGlobalTouchscreenSupportChanged;
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.grpControls = new Krypton.Toolkit.KryptonGroupBox();
+ this.grpAdvancedControls = new Krypton.Toolkit.KryptonGroupBox();
+ this.workspace = new Krypton.Workspace.KryptonWorkspace();
+ this.navigator = new Krypton.Navigator.KryptonNavigator();
+ this.grpInputControls = new Krypton.Toolkit.KryptonGroupBox();
+ this.txtInput = new Krypton.Toolkit.KryptonTextBox();
+ this.txtNumeric = new Krypton.Toolkit.KryptonNumericUpDown();
+ this.cmbOptions = new Krypton.Toolkit.KryptonComboBox();
+ this.grpButtons = new Krypton.Toolkit.KryptonGroupBox();
+ this.btnStandard = new Krypton.Toolkit.KryptonButton();
+ this.btnPrimary = new Krypton.Toolkit.KryptonButton();
+ this.btnSuccess = new Krypton.Toolkit.KryptonButton();
+ this.grpCheckboxes = new Krypton.Toolkit.KryptonGroupBox();
+ this.chkOption1 = new Krypton.Toolkit.KryptonCheckBox();
+ this.chkOption2 = new Krypton.Toolkit.KryptonCheckBox();
+ this.chkOption3 = new Krypton.Toolkit.KryptonCheckBox();
+ this.grpRadioButtons = new Krypton.Toolkit.KryptonGroupBox();
+ this.radioOption1 = new Krypton.Toolkit.KryptonRadioButton();
+ this.radioOption2 = new Krypton.Toolkit.KryptonRadioButton();
+ this.radioOption3 = new Krypton.Toolkit.KryptonRadioButton();
+ this.grpOtherControls = new Krypton.Toolkit.KryptonGroupBox();
+ this.progressBar = new Krypton.Toolkit.KryptonProgressBar();
+ this.trackBar = new Krypton.Toolkit.KryptonTrackBar();
+ this.grpSettings = new Krypton.Toolkit.KryptonGroupBox();
+ this.grpDpiInfo = new Krypton.Toolkit.KryptonGroupBox();
+ this.lblScalingExample = new Krypton.Toolkit.KryptonLabel();
+ this.lblDpiWarning = new Krypton.Toolkit.KryptonLabel();
+ this.lblCombinedPerMonitor = new Krypton.Toolkit.KryptonLabel();
+ this.lblCombinedPrimary = new Krypton.Toolkit.KryptonLabel();
+ this.lblDpiActual = new Krypton.Toolkit.KryptonLabel();
+ this.lblDpiPerMonitor = new Krypton.Toolkit.KryptonLabel();
+ this.lblDpiPrimary = new Krypton.Toolkit.KryptonLabel();
+ this.btnRefreshDpi = new Krypton.Toolkit.KryptonButton();
+ this.lblStatus = new Krypton.Toolkit.KryptonLabel();
+ this.btnToggle = new Krypton.Toolkit.KryptonButton();
+ this.btnApplyPreset75 = new Krypton.Toolkit.KryptonButton();
+ this.btnApplyPreset50 = new Krypton.Toolkit.KryptonButton();
+ this.btnApplyPreset25 = new Krypton.Toolkit.KryptonButton();
+ this.btnResetScale = new Krypton.Toolkit.KryptonButton();
+ this.lblScaleValue = new Krypton.Toolkit.KryptonLabel();
+ this.trackScaleFactor = new Krypton.Toolkit.KryptonTrackBar();
+ this.lblScaleFactor = new Krypton.Toolkit.KryptonLabel();
+ this.chkEnableTouchscreen = new Krypton.Toolkit.KryptonCheckBox();
+ this.chkEnableFontScaling = new Krypton.Toolkit.KryptonCheckBox();
+ this.lblFontScaleFactor = new Krypton.Toolkit.KryptonLabel();
+ this.trackFontScaleFactor = new Krypton.Toolkit.KryptonTrackBar();
+ this.lblFontScaleValue = new Krypton.Toolkit.KryptonLabel();
+ ((System.ComponentModel.ISupportInitialize)(this.grpControls)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpControls.Panel)).BeginInit();
+ this.grpControls.Panel.SuspendLayout();
+ this.grpControls.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpInputControls)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpInputControls.Panel)).BeginInit();
+ this.grpInputControls.Panel.SuspendLayout();
+ this.grpInputControls.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpButtons)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpButtons.Panel)).BeginInit();
+ this.grpButtons.Panel.SuspendLayout();
+ this.grpButtons.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpCheckboxes)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpCheckboxes.Panel)).BeginInit();
+ this.grpCheckboxes.Panel.SuspendLayout();
+ this.grpCheckboxes.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpRadioButtons)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpRadioButtons.Panel)).BeginInit();
+ this.grpRadioButtons.Panel.SuspendLayout();
+ this.grpRadioButtons.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpOtherControls)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpOtherControls.Panel)).BeginInit();
+ this.grpOtherControls.Panel.SuspendLayout();
+ this.grpOtherControls.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpSettings)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpSettings.Panel)).BeginInit();
+ this.grpSettings.Panel.SuspendLayout();
+ this.grpSettings.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.grpDpiInfo)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.grpDpiInfo.Panel)).BeginInit();
+ this.grpDpiInfo.Panel.SuspendLayout();
+ this.grpDpiInfo.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // grpControls
+ //
+ this.grpControls.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.grpControls.Location = new System.Drawing.Point(0, 0);
+ this.grpControls.Name = "grpControls";
+ this.grpControls.Size = new System.Drawing.Size(1000, 500);
+ this.grpControls.Panel.AutoScroll = true;
+ this.grpControls.TabIndex = 0;
+ this.grpControls.Values.Heading = "Control Examples (These scale with High DPI + Touchscreen support)";
+ //
+ // grpControls.Panel
+ //
+ this.grpControls.Panel.Controls.Add(this.grpAdvancedControls);
+ this.grpControls.Panel.Controls.Add(this.grpOtherControls);
+ this.grpControls.Panel.Controls.Add(this.grpRadioButtons);
+ this.grpControls.Panel.Controls.Add(this.grpCheckboxes);
+ this.grpControls.Panel.Controls.Add(this.grpButtons);
+ this.grpControls.Panel.Controls.Add(this.grpInputControls);
+ //
+ // grpInputControls
+ //
+ this.grpInputControls.Location = new System.Drawing.Point(15, 15);
+ this.grpInputControls.Name = "grpInputControls";
+ this.grpInputControls.Size = new System.Drawing.Size(400, 120);
+ this.grpInputControls.TabIndex = 0;
+ this.grpInputControls.Values.Heading = "Input Controls";
+ //
+ // grpInputControls.Panel
+ //
+ this.grpInputControls.Panel.Controls.Add(this.cmbOptions);
+ this.grpInputControls.Panel.Controls.Add(this.txtNumeric);
+ this.grpInputControls.Panel.Controls.Add(this.txtInput);
+ //
+ // txtInput
+ //
+ this.txtInput.Location = new System.Drawing.Point(15, 20);
+ this.txtInput.Name = "txtInput";
+ this.txtInput.Size = new System.Drawing.Size(370, 27);
+ this.txtInput.TabIndex = 0;
+ //
+ // txtNumeric
+ //
+ this.txtNumeric.Location = new System.Drawing.Point(15, 55);
+ this.txtNumeric.Name = "txtNumeric";
+ this.txtNumeric.Size = new System.Drawing.Size(180, 27);
+ this.txtNumeric.TabIndex = 1;
+ //
+ // cmbOptions
+ //
+ this.cmbOptions.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.cmbOptions.DropDownWidth = 370;
+ this.cmbOptions.Location = new System.Drawing.Point(205, 55);
+ this.cmbOptions.Name = "cmbOptions";
+ this.cmbOptions.Size = new System.Drawing.Size(180, 27);
+ this.cmbOptions.TabIndex = 2;
+ //
+ // grpButtons
+ //
+ this.grpButtons.Location = new System.Drawing.Point(430, 15);
+ this.grpButtons.Name = "grpButtons";
+ this.grpButtons.Size = new System.Drawing.Size(430, 120);
+ this.grpButtons.TabIndex = 1;
+ this.grpButtons.Values.Heading = "Buttons";
+ //
+ // grpButtons.Panel
+ //
+ this.grpButtons.Panel.Controls.Add(this.btnSuccess);
+ this.grpButtons.Panel.Controls.Add(this.btnPrimary);
+ this.grpButtons.Panel.Controls.Add(this.btnStandard);
+ //
+ // btnStandard
+ //
+ this.btnStandard.Location = new System.Drawing.Point(15, 20);
+ this.btnStandard.Name = "btnStandard";
+ this.btnStandard.Size = new System.Drawing.Size(120, 35);
+ this.btnStandard.TabIndex = 0;
+ this.btnStandard.Values.Text = "Standard";
+ //
+ // btnPrimary
+ //
+ this.btnPrimary.Location = new System.Drawing.Point(150, 20);
+ this.btnPrimary.Name = "btnPrimary";
+ this.btnPrimary.Size = new System.Drawing.Size(120, 35);
+ this.btnPrimary.TabIndex = 1;
+ this.btnPrimary.Values.Text = "Primary";
+ //
+ // btnSuccess
+ //
+ this.btnSuccess.Location = new System.Drawing.Point(285, 20);
+ this.btnSuccess.Name = "btnSuccess";
+ this.btnSuccess.Size = new System.Drawing.Size(120, 35);
+ this.btnSuccess.TabIndex = 2;
+ this.btnSuccess.Values.Text = "Success";
+ //
+ // grpCheckboxes
+ //
+ this.grpCheckboxes.Location = new System.Drawing.Point(15, 150);
+ this.grpCheckboxes.Name = "grpCheckboxes";
+ this.grpCheckboxes.Size = new System.Drawing.Size(400, 100);
+ this.grpCheckboxes.TabIndex = 2;
+ this.grpCheckboxes.Values.Heading = "Checkboxes";
+ //
+ // grpCheckboxes.Panel
+ //
+ this.grpCheckboxes.Panel.Controls.Add(this.chkOption3);
+ this.grpCheckboxes.Panel.Controls.Add(this.chkOption2);
+ this.grpCheckboxes.Panel.Controls.Add(this.chkOption1);
+ //
+ // chkOption1
+ //
+ this.chkOption1.Location = new System.Drawing.Point(15, 20);
+ this.chkOption1.Name = "chkOption1";
+ this.chkOption1.Size = new System.Drawing.Size(100, 20);
+ this.chkOption1.TabIndex = 0;
+ this.chkOption1.Values.Text = "Option 1";
+ //
+ // chkOption2
+ //
+ this.chkOption2.Location = new System.Drawing.Point(15, 50);
+ this.chkOption2.Name = "chkOption2";
+ this.chkOption2.Size = new System.Drawing.Size(100, 20);
+ this.chkOption2.TabIndex = 1;
+ this.chkOption2.Values.Text = "Option 2";
+ //
+ // chkOption3
+ //
+ this.chkOption3.Location = new System.Drawing.Point(150, 20);
+ this.chkOption3.Name = "chkOption3";
+ this.chkOption3.Size = new System.Drawing.Size(100, 20);
+ this.chkOption3.TabIndex = 2;
+ this.chkOption3.Values.Text = "Option 3";
+ //
+ // grpRadioButtons
+ //
+ this.grpRadioButtons.Location = new System.Drawing.Point(430, 150);
+ this.grpRadioButtons.Name = "grpRadioButtons";
+ this.grpRadioButtons.Size = new System.Drawing.Size(430, 100);
+ this.grpRadioButtons.TabIndex = 3;
+ this.grpRadioButtons.Values.Heading = "Radio Buttons";
+ //
+ // grpRadioButtons.Panel
+ //
+ this.grpRadioButtons.Panel.Controls.Add(this.radioOption3);
+ this.grpRadioButtons.Panel.Controls.Add(this.radioOption2);
+ this.grpRadioButtons.Panel.Controls.Add(this.radioOption1);
+ //
+ // radioOption1
+ //
+ this.radioOption1.Location = new System.Drawing.Point(15, 20);
+ this.radioOption1.Name = "radioOption1";
+ this.radioOption1.Size = new System.Drawing.Size(120, 20);
+ this.radioOption1.TabIndex = 0;
+ this.radioOption1.Values.Text = "Radio Option A";
+ //
+ // radioOption2
+ //
+ this.radioOption2.Location = new System.Drawing.Point(15, 50);
+ this.radioOption2.Name = "radioOption2";
+ this.radioOption2.Size = new System.Drawing.Size(120, 20);
+ this.radioOption2.TabIndex = 1;
+ this.radioOption2.Values.Text = "Radio Option B";
+ //
+ // radioOption3
+ //
+ this.radioOption3.Location = new System.Drawing.Point(150, 20);
+ this.radioOption3.Name = "radioOption3";
+ this.radioOption3.Size = new System.Drawing.Size(120, 20);
+ this.radioOption3.TabIndex = 2;
+ this.radioOption3.Values.Text = "Radio Option C";
+ //
+ // grpOtherControls
+ //
+ this.grpOtherControls.Location = new System.Drawing.Point(15, 265);
+ this.grpOtherControls.Name = "grpOtherControls";
+ this.grpOtherControls.Size = new System.Drawing.Size(845, 100);
+ this.grpOtherControls.TabIndex = 4;
+ this.grpOtherControls.Values.Heading = "Other Controls";
+ //
+ // grpOtherControls.Panel
+ //
+ this.grpOtherControls.Panel.Controls.Add(this.trackBar);
+ this.grpOtherControls.Panel.Controls.Add(this.progressBar);
+ //
+ // progressBar
+ //
+ this.progressBar.Location = new System.Drawing.Point(15, 20);
+ this.progressBar.Name = "progressBar";
+ this.progressBar.Size = new System.Drawing.Size(400, 25);
+ this.progressBar.TabIndex = 0;
+ this.progressBar.Value = 65;
+ //
+ // trackBar
+ //
+ this.trackBar.Location = new System.Drawing.Point(15, 55);
+ this.trackBar.Name = "trackBar";
+ this.trackBar.Size = new System.Drawing.Size(400, 45);
+ this.trackBar.TabIndex = 1;
+ this.trackBar.TickFrequency = 10;
+ //
+ // grpAdvancedControls
+ //
+ this.grpAdvancedControls.Location = new System.Drawing.Point(15, 380);
+ this.grpAdvancedControls.Name = "grpAdvancedControls";
+ this.grpAdvancedControls.Size = new System.Drawing.Size(845, 100);
+ this.grpAdvancedControls.TabIndex = 5;
+ this.grpAdvancedControls.Values.Heading = "Advanced Controls (Navigator & Workspace - Per-Monitor DPI aware)";
+ //
+ // grpAdvancedControls.Panel
+ //
+ this.grpAdvancedControls.Panel.Controls.Add(this.workspace);
+ this.grpAdvancedControls.Panel.Controls.Add(this.navigator);
+ //
+ // navigator
+ //
+ this.navigator.Bar.BarFirstItemInset = 0;
+ this.navigator.Bar.BarLastItemInset = 0;
+ this.navigator.Bar.BarMinimumHeight = 0;
+ this.navigator.Bar.TabStyle = Krypton.Toolkit.TabStyle.StandardProfile;
+ this.navigator.Button.ButtonDisplayLogic = Krypton.Navigator.ButtonDisplayLogic.None;
+ this.navigator.Button.ContextButtonAction = Krypton.Navigator.ContextButtonAction.None;
+ this.navigator.Dock = System.Windows.Forms.DockStyle.Left;
+ this.navigator.Location = new System.Drawing.Point(15, 20);
+ this.navigator.Name = "navigator";
+ this.navigator.NavigatorMode = Krypton.Navigator.NavigatorMode.BarTabGroup;
+ this.navigator.Size = new System.Drawing.Size(250, 60);
+ this.navigator.TabIndex = 0;
+ //
+ // workspace
+ //
+ this.workspace.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.workspace.Location = new System.Drawing.Point(265, 20);
+ this.workspace.Name = "workspace";
+ this.workspace.Size = new System.Drawing.Size(565, 60);
+ this.workspace.TabIndex = 1;
+ //
+ // grpSettings
+ //
+ this.grpSettings.Dock = System.Windows.Forms.DockStyle.Bottom;
+ this.grpSettings.Location = new System.Drawing.Point(0, 500);
+ this.grpSettings.Name = "grpSettings";
+ this.grpSettings.Size = new System.Drawing.Size(1000, 500);
+ this.grpSettings.TabIndex = 1;
+ this.grpSettings.Values.Heading = "Touchscreen + High DPI Settings";
+ //
+ // grpSettings.Panel
+ //
+ this.grpSettings.Panel.Controls.Add(this.grpDpiInfo);
+ this.grpSettings.Panel.Controls.Add(this.lblStatus);
+ this.grpSettings.Panel.Controls.Add(this.btnToggle);
+ this.grpSettings.Panel.Controls.Add(this.btnApplyPreset75);
+ this.grpSettings.Panel.Controls.Add(this.btnApplyPreset50);
+ this.grpSettings.Panel.Controls.Add(this.btnApplyPreset25);
+ this.grpSettings.Panel.Controls.Add(this.btnResetScale);
+ this.grpSettings.Panel.Controls.Add(this.lblScaleValue);
+ this.grpSettings.Panel.Controls.Add(this.trackScaleFactor);
+ this.grpSettings.Panel.Controls.Add(this.lblScaleFactor);
+ this.grpSettings.Panel.Controls.Add(this.chkEnableTouchscreen);
+ this.grpSettings.Panel.Controls.Add(this.chkEnableFontScaling);
+ this.grpSettings.Panel.Controls.Add(this.lblFontScaleFactor);
+ this.grpSettings.Panel.Controls.Add(this.trackFontScaleFactor);
+ this.grpSettings.Panel.Controls.Add(this.lblFontScaleValue);
+ //
+ // chkEnableTouchscreen
+ //
+ this.chkEnableTouchscreen.Location = new System.Drawing.Point(15, 20);
+ this.chkEnableTouchscreen.Name = "chkEnableTouchscreen";
+ this.chkEnableTouchscreen.Size = new System.Drawing.Size(200, 20);
+ this.chkEnableTouchscreen.TabIndex = 0;
+ this.chkEnableTouchscreen.Values.Text = "Enable Touchscreen Support";
+ //
+ // lblScaleFactor
+ //
+ this.lblScaleFactor.Location = new System.Drawing.Point(15, 50);
+ this.lblScaleFactor.Name = "lblScaleFactor";
+ this.lblScaleFactor.Size = new System.Drawing.Size(200, 20);
+ this.lblScaleFactor.TabIndex = 1;
+ this.lblScaleFactor.Values.Text = "Scale Factor (1.0x - 3.0x):";
+ //
+ // trackScaleFactor
+ //
+ this.trackScaleFactor.Location = new System.Drawing.Point(15, 75);
+ this.trackScaleFactor.Maximum = 200;
+ this.trackScaleFactor.Minimum = 0;
+ this.trackScaleFactor.Name = "trackScaleFactor";
+ this.trackScaleFactor.Size = new System.Drawing.Size(400, 45);
+ this.trackScaleFactor.TabIndex = 2;
+ this.trackScaleFactor.TickFrequency = 25;
+ this.trackScaleFactor.Value = 25;
+ //
+ // lblScaleValue
+ //
+ this.lblScaleValue.Location = new System.Drawing.Point(430, 75);
+ this.lblScaleValue.Name = "lblScaleValue";
+ this.lblScaleValue.Size = new System.Drawing.Size(200, 20);
+ this.lblScaleValue.TabIndex = 3;
+ this.lblScaleValue.Values.Text = "1.25x (25.0% larger)";
+ //
+ // btnResetScale
+ //
+ this.btnResetScale.Location = new System.Drawing.Point(650, 75);
+ this.btnResetScale.Name = "btnResetScale";
+ this.btnResetScale.Size = new System.Drawing.Size(100, 35);
+ this.btnResetScale.TabIndex = 4;
+ this.btnResetScale.Values.Text = "Reset (1.25x)";
+ //
+ // btnApplyPreset25
+ //
+ this.btnApplyPreset25.Location = new System.Drawing.Point(15, 130);
+ this.btnApplyPreset25.Name = "btnApplyPreset25";
+ this.btnApplyPreset25.Size = new System.Drawing.Size(120, 35);
+ this.btnApplyPreset25.TabIndex = 5;
+ this.btnApplyPreset25.Values.Text = "Preset: 25%";
+ //
+ // btnApplyPreset50
+ //
+ this.btnApplyPreset50.Location = new System.Drawing.Point(150, 130);
+ this.btnApplyPreset50.Name = "btnApplyPreset50";
+ this.btnApplyPreset50.Size = new System.Drawing.Size(120, 35);
+ this.btnApplyPreset50.TabIndex = 6;
+ this.btnApplyPreset50.Values.Text = "Preset: 50%";
+ //
+ // btnApplyPreset75
+ //
+ this.btnApplyPreset75.Location = new System.Drawing.Point(285, 130);
+ this.btnApplyPreset75.Name = "btnApplyPreset75";
+ this.btnApplyPreset75.Size = new System.Drawing.Size(120, 35);
+ this.btnApplyPreset75.TabIndex = 7;
+ this.btnApplyPreset75.Values.Text = "Preset: 75%";
+ //
+ // btnToggle
+ //
+ this.btnToggle.Location = new System.Drawing.Point(430, 130);
+ this.btnToggle.Name = "btnToggle";
+ this.btnToggle.Size = new System.Drawing.Size(200, 35);
+ this.btnToggle.TabIndex = 8;
+ this.btnToggle.Values.Text = "Toggle Support";
+ //
+ // chkEnableFontScaling
+ //
+ this.chkEnableFontScaling.Location = new System.Drawing.Point(15, 180);
+ this.chkEnableFontScaling.Name = "chkEnableFontScaling";
+ this.chkEnableFontScaling.Size = new System.Drawing.Size(200, 20);
+ this.chkEnableFontScaling.TabIndex = 9;
+ this.chkEnableFontScaling.Values.Text = "Enable Font Scaling";
+ //
+ // lblFontScaleFactor
+ //
+ this.lblFontScaleFactor.Location = new System.Drawing.Point(15, 210);
+ this.lblFontScaleFactor.Name = "lblFontScaleFactor";
+ this.lblFontScaleFactor.Size = new System.Drawing.Size(200, 20);
+ this.lblFontScaleFactor.TabIndex = 10;
+ this.lblFontScaleFactor.Values.Text = "Font Scale Factor (1.0x - 3.0x):";
+ //
+ // trackFontScaleFactor
+ //
+ this.trackFontScaleFactor.Location = new System.Drawing.Point(15, 235);
+ this.trackFontScaleFactor.Maximum = 200;
+ this.trackFontScaleFactor.Minimum = 0;
+ this.trackFontScaleFactor.Name = "trackFontScaleFactor";
+ this.trackFontScaleFactor.Size = new System.Drawing.Size(400, 45);
+ this.trackFontScaleFactor.TabIndex = 11;
+ this.trackFontScaleFactor.TickFrequency = 25;
+ this.trackFontScaleFactor.Value = 25;
+ //
+ // lblFontScaleValue
+ //
+ this.lblFontScaleValue.Location = new System.Drawing.Point(430, 235);
+ this.lblFontScaleValue.Name = "lblFontScaleValue";
+ this.lblFontScaleValue.Size = new System.Drawing.Size(200, 20);
+ this.lblFontScaleValue.TabIndex = 12;
+ this.lblFontScaleValue.Values.Text = "1.25x (25.0% larger)";
+ //
+ // grpDpiInfo
+ //
+ this.grpDpiInfo.Location = new System.Drawing.Point(15, 290);
+ this.grpDpiInfo.Name = "grpDpiInfo";
+ this.grpDpiInfo.Size = new System.Drawing.Size(970, 190);
+ this.grpDpiInfo.TabIndex = 13;
+ this.grpDpiInfo.Values.Heading = "High DPI Information (Per-Monitor DPI Awareness)";
+ //
+ // grpDpiInfo.Panel
+ //
+ this.grpDpiInfo.Panel.Controls.Add(this.lblScalingExample);
+ this.grpDpiInfo.Panel.Controls.Add(this.lblDpiWarning);
+ this.grpDpiInfo.Panel.Controls.Add(this.lblCombinedPerMonitor);
+ this.grpDpiInfo.Panel.Controls.Add(this.lblCombinedPrimary);
+ this.grpDpiInfo.Panel.Controls.Add(this.lblDpiActual);
+ this.grpDpiInfo.Panel.Controls.Add(this.lblDpiPerMonitor);
+ this.grpDpiInfo.Panel.Controls.Add(this.lblDpiPrimary);
+ this.grpDpiInfo.Panel.Controls.Add(this.btnRefreshDpi);
+ //
+ // btnRefreshDpi
+ //
+ this.btnRefreshDpi.Location = new System.Drawing.Point(850, 20);
+ this.btnRefreshDpi.Name = "btnRefreshDpi";
+ this.btnRefreshDpi.Size = new System.Drawing.Size(100, 35);
+ this.btnRefreshDpi.TabIndex = 0;
+ this.btnRefreshDpi.Values.Text = "Refresh DPI";
+ //
+ // lblDpiPrimary
+ //
+ this.lblDpiPrimary.Location = new System.Drawing.Point(15, 20);
+ this.lblDpiPrimary.Name = "lblDpiPrimary";
+ this.lblDpiPrimary.Size = new System.Drawing.Size(400, 20);
+ this.lblDpiPrimary.TabIndex = 1;
+ this.lblDpiPrimary.Values.Text = "Primary Monitor DPI: 1.00x (1.00x, 1.00y)";
+ //
+ // lblDpiPerMonitor
+ //
+ this.lblDpiPerMonitor.Location = new System.Drawing.Point(15, 50);
+ this.lblDpiPerMonitor.Name = "lblDpiPerMonitor";
+ this.lblDpiPerMonitor.Size = new System.Drawing.Size(400, 20);
+ this.lblDpiPerMonitor.TabIndex = 2;
+ this.lblDpiPerMonitor.Values.Text = "Per-Monitor DPI: 1.00x (1.00x, 1.00y)";
+ //
+ // lblDpiActual
+ //
+ this.lblDpiActual.Location = new System.Drawing.Point(15, 80);
+ this.lblDpiActual.Name = "lblDpiActual";
+ this.lblDpiActual.Size = new System.Drawing.Size(400, 20);
+ this.lblDpiActual.TabIndex = 3;
+ this.lblDpiActual.Values.Text = "Windows API DPI: Not available";
+ //
+ // lblCombinedPrimary
+ //
+ this.lblCombinedPrimary.Location = new System.Drawing.Point(430, 20);
+ this.lblCombinedPrimary.Name = "lblCombinedPrimary";
+ this.lblCombinedPrimary.Size = new System.Drawing.Size(400, 20);
+ this.lblCombinedPrimary.TabIndex = 4;
+ this.lblCombinedPrimary.Values.Text = "Combined (Primary): 1.00x (1.00x, 1.00y)";
+ //
+ // lblCombinedPerMonitor
+ //
+ this.lblCombinedPerMonitor.Location = new System.Drawing.Point(430, 50);
+ this.lblCombinedPerMonitor.Name = "lblCombinedPerMonitor";
+ this.lblCombinedPerMonitor.Size = new System.Drawing.Size(400, 20);
+ this.lblCombinedPerMonitor.TabIndex = 5;
+ this.lblCombinedPerMonitor.Values.Text = "Combined (Per-Monitor): 1.00x (1.00x, 1.00y)";
+ //
+ // lblDpiWarning
+ //
+ this.lblDpiWarning.Location = new System.Drawing.Point(15, 110);
+ this.lblDpiWarning.Name = "lblDpiWarning";
+ this.lblDpiWarning.Size = new System.Drawing.Size(815, 20);
+ this.lblDpiWarning.TabIndex = 6;
+ this.lblDpiWarning.Values.Text = "✓ Single monitor or matching DPI";
+ //
+ // lblScalingExample
+ //
+ this.lblScalingExample.Location = new System.Drawing.Point(15, 140);
+ this.lblScalingExample.Name = "lblScalingExample";
+ this.lblScalingExample.Size = new System.Drawing.Size(815, 40);
+ this.lblScalingExample.TabIndex = 7;
+ this.lblScalingExample.Values.Text = "Scaling Example (base=100px): DPI only=100px, DPI+Touchscreen=100px, Per-Monitor=100px";
+ //
+ // lblStatus
+ //
+ this.lblStatus.Location = new System.Drawing.Point(650, 20);
+ this.lblStatus.Name = "lblStatus";
+ this.lblStatus.Size = new System.Drawing.Size(335, 50);
+ this.lblStatus.TabIndex = 14;
+ this.lblStatus.Values.Text = "Status: Disabled";
+ //
+ // TouchscreenHighDpiDemo
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(1000, 1000);
+ this.Controls.Add(this.grpControls);
+ this.Controls.Add(this.grpSettings);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;
+ this.MinimumSize = new System.Drawing.Size(1020, 1020);
+ this.Name = "TouchscreenHighDpiDemo";
+ this.Text = "Touchscreen + High DPI Scaling Demo (Issue #2844)";
+ ((System.ComponentModel.ISupportInitialize)(this.grpControls)).EndInit();
+ this.grpControls.Panel.ResumeLayout(false);
+ this.grpControls.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpInputControls)).EndInit();
+ this.grpInputControls.Panel.ResumeLayout(false);
+ this.grpInputControls.Panel.PerformLayout();
+ this.grpInputControls.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpButtons)).EndInit();
+ this.grpButtons.Panel.ResumeLayout(false);
+ this.grpButtons.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpCheckboxes)).EndInit();
+ this.grpCheckboxes.Panel.ResumeLayout(false);
+ this.grpCheckboxes.Panel.PerformLayout();
+ this.grpCheckboxes.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpRadioButtons)).EndInit();
+ this.grpRadioButtons.Panel.ResumeLayout(false);
+ this.grpRadioButtons.Panel.PerformLayout();
+ this.grpRadioButtons.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpOtherControls)).EndInit();
+ this.grpOtherControls.Panel.ResumeLayout(false);
+ this.grpOtherControls.Panel.PerformLayout();
+ this.grpOtherControls.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpAdvancedControls)).EndInit();
+ this.grpAdvancedControls.Panel.ResumeLayout(false);
+ this.grpAdvancedControls.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpSettings)).EndInit();
+ this.grpSettings.Panel.ResumeLayout(false);
+ this.grpSettings.Panel.PerformLayout();
+ this.grpSettings.ResumeLayout(false);
+ ((System.ComponentModel.ISupportInitialize)(this.grpDpiInfo)).EndInit();
+ this.grpDpiInfo.Panel.ResumeLayout(false);
+ this.grpDpiInfo.Panel.PerformLayout();
+ this.grpDpiInfo.ResumeLayout(false);
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private Krypton.Toolkit.KryptonGroupBox grpControls;
+ private Krypton.Toolkit.KryptonGroupBox grpAdvancedControls;
+ private Krypton.Navigator.KryptonNavigator navigator;
+ private Krypton.Workspace.KryptonWorkspace workspace;
+ private Krypton.Toolkit.KryptonGroupBox grpInputControls;
+ private Krypton.Toolkit.KryptonTextBox txtInput;
+ private Krypton.Toolkit.KryptonNumericUpDown txtNumeric;
+ private Krypton.Toolkit.KryptonComboBox cmbOptions;
+ private Krypton.Toolkit.KryptonGroupBox grpButtons;
+ private Krypton.Toolkit.KryptonButton btnStandard;
+ private Krypton.Toolkit.KryptonButton btnPrimary;
+ private Krypton.Toolkit.KryptonButton btnSuccess;
+ private Krypton.Toolkit.KryptonGroupBox grpCheckboxes;
+ private Krypton.Toolkit.KryptonCheckBox chkOption1;
+ private Krypton.Toolkit.KryptonCheckBox chkOption2;
+ private Krypton.Toolkit.KryptonCheckBox chkOption3;
+ private Krypton.Toolkit.KryptonGroupBox grpRadioButtons;
+ private Krypton.Toolkit.KryptonRadioButton radioOption1;
+ private Krypton.Toolkit.KryptonRadioButton radioOption2;
+ private Krypton.Toolkit.KryptonRadioButton radioOption3;
+ private Krypton.Toolkit.KryptonGroupBox grpOtherControls;
+ private Krypton.Toolkit.KryptonProgressBar progressBar;
+ private Krypton.Toolkit.KryptonTrackBar trackBar;
+ private Krypton.Toolkit.KryptonGroupBox grpSettings;
+ private Krypton.Toolkit.KryptonCheckBox chkEnableTouchscreen;
+ private Krypton.Toolkit.KryptonLabel lblScaleFactor;
+ private Krypton.Toolkit.KryptonTrackBar trackScaleFactor;
+ private Krypton.Toolkit.KryptonLabel lblScaleValue;
+ private Krypton.Toolkit.KryptonButton btnResetScale;
+ private Krypton.Toolkit.KryptonButton btnApplyPreset25;
+ private Krypton.Toolkit.KryptonButton btnApplyPreset50;
+ private Krypton.Toolkit.KryptonButton btnApplyPreset75;
+ private Krypton.Toolkit.KryptonButton btnToggle;
+ private Krypton.Toolkit.KryptonLabel lblStatus;
+ private Krypton.Toolkit.KryptonCheckBox chkEnableFontScaling;
+ private Krypton.Toolkit.KryptonLabel lblFontScaleFactor;
+ private Krypton.Toolkit.KryptonTrackBar trackFontScaleFactor;
+ private Krypton.Toolkit.KryptonLabel lblFontScaleValue;
+ private Krypton.Toolkit.KryptonGroupBox grpDpiInfo;
+ private Krypton.Toolkit.KryptonButton btnRefreshDpi;
+ private Krypton.Toolkit.KryptonLabel lblDpiPrimary;
+ private Krypton.Toolkit.KryptonLabel lblDpiPerMonitor;
+ private Krypton.Toolkit.KryptonLabel lblDpiActual;
+ private Krypton.Toolkit.KryptonLabel lblCombinedPrimary;
+ private Krypton.Toolkit.KryptonLabel lblCombinedPerMonitor;
+ private Krypton.Toolkit.KryptonLabel lblDpiWarning;
+ private Krypton.Toolkit.KryptonLabel lblScalingExample;
+ }
+}
\ No newline at end of file
diff --git a/Source/Krypton Components/TestForm/TouchscreenHighDpiDemo.cs b/Source/Krypton Components/TestForm/TouchscreenHighDpiDemo.cs
new file mode 100644
index 000000000..38ae62381
--- /dev/null
+++ b/Source/Krypton Components/TestForm/TouchscreenHighDpiDemo.cs
@@ -0,0 +1,479 @@
+#region BSD License
+/*
+ *
+ * New BSD 3-Clause License (https://github.com/Krypton-Suite/Standard-Toolkit/blob/master/LICENSE)
+ * Modifications by Peter Wagner(aka Wagnerp) & Simon Coghlan(aka Smurf-IV), et al. 2026 - 2026. All rights reserved.
+ *
+ */
+#endregion
+
+using System.Runtime.InteropServices;
+
+using Krypton.Navigator;
+using Krypton.Ribbon;
+using Krypton.Toolkit;
+using Krypton.Workspace;
+
+namespace TestForm;
+
+///
+/// Comprehensive demonstration of touchscreen support with high DPI scaling.
+/// Shows per-monitor DPI awareness, combined scaling factors (DPI × Touchscreen),
+/// and real-time monitoring of DPI changes when windows move between monitors.
+///
+public partial class TouchscreenHighDpiDemo : KryptonForm
+{
+ private Timer _dpiMonitorTimer;
+ private bool _updatingFromEvent;
+
+ public TouchscreenHighDpiDemo()
+ {
+ InitializeComponent();
+ InitializeForm();
+ }
+
+ private void InitializeForm()
+ {
+ // Subscribe to touchscreen support changes
+ KryptonManager.GlobalTouchscreenSupportChanged += OnGlobalTouchscreenSupportChanged;
+
+ // Setup DPI monitoring timer
+ _dpiMonitorTimer = new Timer { Interval = 500 };
+ _dpiMonitorTimer.Tick += DpiMonitorTimer_Tick;
+ _dpiMonitorTimer.Start();
+
+ // Initialize UI with current settings
+ UpdateUIFromSettings();
+
+ // Setup demo controls
+ SetupDemoControls();
+
+ // Setup event handlers
+ chkEnableTouchscreen.CheckedChanged += ChkEnableTouchscreen_CheckedChanged;
+ trackScaleFactor.ValueChanged += TrackScaleFactor_ValueChanged;
+ chkEnableFontScaling.CheckedChanged += ChkEnableFontScaling_CheckedChanged;
+ trackFontScaleFactor.ValueChanged += TrackFontScaleFactor_ValueChanged;
+ btnResetScale.Click += BtnResetScale_Click;
+ btnApplyPreset25.Click += BtnApplyPreset25_Click;
+ btnApplyPreset50.Click += BtnApplyPreset50_Click;
+ btnApplyPreset75.Click += BtnApplyPreset75_Click;
+ btnToggle.Click += BtnToggle_Click;
+ btnRefreshDpi.Click += BtnRefreshDpi_Click;
+
+ // Handle form move/resize to detect monitor changes
+ this.Move += (s, e) => UpdateDpiInfo();
+ this.Resize += (s, e) => UpdateDpiInfo();
+ this.DpiChanged += (s, e) => OnDpiChanged(e);
+
+ // Update status
+ UpdateStatus();
+ UpdateDpiInfo();
+ }
+
+ private void SetupDemoControls()
+ {
+ // Button examples
+ btnStandard.Text = "Standard Button";
+ btnStandard.Click += (s, e) => KryptonMessageBox.Show("Standard button clicked!", "High DPI + Touchscreen Demo");
+
+ btnPrimary.Text = "Primary Button";
+ btnPrimary.ButtonStyle = ButtonStyle.Command;
+ btnPrimary.Click += (s, e) => KryptonMessageBox.Show("Primary button clicked!", "High DPI + Touchscreen Demo");
+
+ btnSuccess.Text = "Success Button";
+ btnSuccess.StateCommon.Content.ShortText.Color1 = Color.Green;
+ btnSuccess.Click += (s, e) => KryptonMessageBox.Show("Success button clicked!", "High DPI + Touchscreen Demo");
+
+ // Checkbox examples
+ chkOption1.Text = "Option 1";
+ chkOption2.Text = "Option 2";
+ chkOption3.Text = "Option 3";
+
+ // Radio button examples
+ radioOption1.Text = "Radio Option A";
+ radioOption2.Text = "Radio Option B";
+ radioOption3.Text = "Radio Option C";
+ radioOption1.Checked = true;
+
+ // Text input examples
+ txtInput.Text = "Sample text input";
+ txtInput.CueHint.CueHintText = "Enter text here...";
+ txtNumeric.Value = 42;
+
+ // ComboBox example
+ cmbOptions.Items.AddRange(new[] { "Option 1", "Option 2", "Option 3", "Option 4" });
+ cmbOptions.SelectedIndex = 0;
+
+ // Progress bar
+ progressBar.Value = 65;
+ progressBar.StateCommon.Content.LongText.Color1 = Color.Blue;
+
+ // Track bar
+ trackBar.Minimum = 0;
+ trackBar.Maximum = 100;
+ trackBar.Value = 50;
+ trackBar.TickFrequency = 10;
+
+ // Navigator example - Create pages first
+ var page1 = new KryptonPage { Text = "Page 1", TextTitle = "First Page" };
+ var label1 = new KryptonLabel
+ {
+ Text = "Navigator Page 1 - High DPI + Touchscreen scaling applies to tabs and buttons",
+ Dock = DockStyle.Fill
+ };
+ label1.StateCommon.ShortText.TextH = PaletteRelativeAlign.Center;
+ label1.StateCommon.ShortText.TextV = PaletteRelativeAlign.Center;
+ page1.Controls.Add(label1);
+ navigator.Pages.Add(page1);
+
+ var page2 = new KryptonPage { Text = "Page 2", TextTitle = "Second Page" };
+ var label2 = new KryptonLabel
+ {
+ Text = "Navigator Page 2 - All controls scale when touchscreen support is enabled on high DPI displays",
+ Dock = DockStyle.Fill
+ };
+ label2.StateCommon.ShortText.TextH = PaletteRelativeAlign.Center;
+ label2.StateCommon.ShortText.TextV = PaletteRelativeAlign.Center;
+ page2.Controls.Add(label2);
+ navigator.Pages.Add(page2);
+
+ navigator.SelectedPage = page1;
+
+ // Workspace example - Create cells with pages
+ var cell1 = new KryptonWorkspaceCell();
+ var workspacePage1 = new KryptonPage { Text = "Workspace Cell 1", TextTitle = "Cell 1" };
+ var label1w = new KryptonLabel
+ {
+ Text = "Workspace Cell 1 - Workspace cells and their tabs scale with touchscreen support on high DPI",
+ Dock = DockStyle.Fill
+ };
+ label1w.StateCommon.ShortText.TextH = PaletteRelativeAlign.Center;
+ label1w.StateCommon.ShortText.TextV = PaletteRelativeAlign.Center;
+ workspacePage1.Controls.Add(label1w);
+ cell1.Pages.Add(workspacePage1);
+ cell1.SelectedPage = workspacePage1;
+
+ var cell2 = new KryptonWorkspaceCell();
+ var workspacePage2 = new KryptonPage { Text = "Workspace Cell 2", TextTitle = "Cell 2" };
+ var label2w = new KryptonLabel
+ {
+ Text = "Workspace Cell 2 - Navigator, Ribbon, Workspace, and Docking all support touchscreen scaling with per-monitor DPI",
+ Dock = DockStyle.Fill
+ };
+ label2w.StateCommon.ShortText.TextH = PaletteRelativeAlign.Center;
+ label2w.StateCommon.ShortText.TextV = PaletteRelativeAlign.Center;
+ workspacePage2.Controls.Add(label2w);
+ cell2.Pages.Add(workspacePage2);
+ cell2.SelectedPage = workspacePage2;
+
+ workspace.Root.Children.Add(cell1);
+ workspace.Root.Children.Add(cell2);
+ }
+
+ private void ChkEnableTouchscreen_CheckedChanged(object? sender, EventArgs e)
+ {
+ if (_updatingFromEvent) return;
+
+ try
+ {
+ KryptonManager.TouchscreenSettingsValues.TouchscreenModeEnabled = chkEnableTouchscreen.Checked;
+ UpdateStatus();
+ UpdateDpiInfo();
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void TrackScaleFactor_ValueChanged(object? sender, EventArgs e)
+ {
+ if (_updatingFromEvent) return;
+
+ try
+ {
+ float scaleFactor = 1.0f + (trackScaleFactor.Value / 100f);
+ KryptonManager.TouchscreenSettingsValues.ControlScaleFactor = scaleFactor;
+ lblScaleValue.Text = $"{scaleFactor:F2}x ({(scaleFactor * 100 - 100):F1}% larger)";
+ UpdateStatus();
+ UpdateDpiInfo();
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void ChkEnableFontScaling_CheckedChanged(object? sender, EventArgs e)
+ {
+ if (_updatingFromEvent) return;
+
+ try
+ {
+ KryptonManager.TouchscreenSettingsValues.FontScalingEnabled = chkEnableFontScaling.Checked;
+ trackFontScaleFactor.Enabled = KryptonManager.TouchscreenSettingsValues.TouchscreenModeEnabled && chkEnableFontScaling.Checked;
+ UpdateStatus();
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void TrackFontScaleFactor_ValueChanged(object? sender, EventArgs e)
+ {
+ if (_updatingFromEvent) return;
+
+ try
+ {
+ float scaleFactor = 1.0f + (trackFontScaleFactor.Value / 100f);
+ KryptonManager.TouchscreenSettingsValues.FontScaleFactor = scaleFactor;
+ lblFontScaleValue.Text = $"{scaleFactor:F2}x ({(scaleFactor * 100 - 100):F1}% larger)";
+ UpdateStatus();
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void BtnResetScale_Click(object? sender, EventArgs e)
+ {
+ try
+ {
+ KryptonManager.TouchscreenSettingsValues.ControlScaleFactor = 1.25f; // Default 25% larger
+ KryptonManager.TouchscreenSettingsValues.FontScaleFactor = 1.25f; // Default 25% larger
+ UpdateUIFromSettings();
+ UpdateStatus();
+ UpdateDpiInfo();
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void BtnApplyPreset25_Click(object? sender, EventArgs e)
+ {
+ ApplyPreset(1.25f, "25% larger (1.25x)");
+ }
+
+ private void BtnApplyPreset50_Click(object? sender, EventArgs e)
+ {
+ ApplyPreset(1.50f, "50% larger (1.50x)");
+ }
+
+ private void BtnApplyPreset75_Click(object? sender, EventArgs e)
+ {
+ ApplyPreset(1.75f, "75% larger (1.75x)");
+ }
+
+ private void ApplyPreset(float scaleFactor, string description)
+ {
+ try
+ {
+ KryptonManager.TouchscreenSettingsValues.TouchscreenModeEnabled = true;
+ KryptonManager.TouchscreenSettingsValues.ControlScaleFactor = scaleFactor;
+ KryptonManager.TouchscreenSettingsValues.FontScaleFactor = scaleFactor; // Match font scale to control scale
+ UpdateUIFromSettings();
+ UpdateStatus();
+ UpdateDpiInfo();
+ KryptonMessageBox.Show($"Applied preset: {description}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Information);
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void BtnToggle_Click(object? sender, EventArgs e)
+ {
+ try
+ {
+ KryptonManager.TouchscreenSettingsValues.TouchscreenModeEnabled = !KryptonManager.UseTouchscreenSupport;
+ UpdateUIFromSettings();
+ UpdateStatus();
+ UpdateDpiInfo();
+ }
+ catch (Exception ex)
+ {
+ KryptonMessageBox.Show($"Error: {ex.Message}", "Touchscreen Support", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error);
+ }
+ }
+
+ private void BtnRefreshDpi_Click(object? sender, EventArgs e)
+ {
+ // Invalidate DPI cache and refresh
+ KryptonManager.InvalidateDpiCache();
+ UpdateDpiInfo();
+ }
+
+ private void OnDpiChanged(DpiChangedEventArgs e)
+ {
+ // DPI changed - invalidate cache and update info
+ KryptonManager.InvalidateDpiCache();
+ UpdateDpiInfo();
+ UpdateStatus();
+ }
+
+ private void DpiMonitorTimer_Tick(object? sender, EventArgs e)
+ {
+ // Periodically update DPI info to catch monitor changes
+ UpdateDpiInfo();
+ }
+
+ private void OnGlobalTouchscreenSupportChanged(object? sender, EventArgs e)
+ {
+ // Update UI when settings change externally
+ if (InvokeRequired)
+ {
+ Invoke(new Action(UpdateUIFromSettings));
+ Invoke(new Action(UpdateStatus));
+ Invoke(new Action(UpdateDpiInfo));
+ }
+ else
+ {
+ UpdateUIFromSettings();
+ UpdateStatus();
+ UpdateDpiInfo();
+ }
+ }
+
+ private void UpdateUIFromSettings()
+ {
+ _updatingFromEvent = true;
+ try
+ {
+ var settings = KryptonManager.TouchscreenSettingsValues;
+
+ chkEnableTouchscreen.Checked = settings.TouchscreenModeEnabled;
+
+ // Convert control scale factor (1.0 - 3.0) to trackbar value (0-200)
+ float controlScaleFactor = settings.ControlScaleFactor;
+ int trackValue = (int)Math.Round((controlScaleFactor - 1.0f) * 100f);
+ trackValue = Math.Max(0, Math.Min(200, trackValue)); // Clamp to valid range
+ trackScaleFactor.Value = trackValue;
+ lblScaleValue.Text = $"{controlScaleFactor:F2}x ({(controlScaleFactor * 100 - 100):F1}% larger)";
+
+ // Font scaling controls
+ chkEnableFontScaling.Checked = settings.FontScalingEnabled;
+
+ // Convert font scale factor (1.0 - 3.0) to trackbar value (0-200)
+ float fontScaleFactor = settings.FontScaleFactor;
+ int fontTrackValue = (int)Math.Round((fontScaleFactor - 1.0f) * 100f);
+ fontTrackValue = Math.Max(0, Math.Min(200, fontTrackValue)); // Clamp to valid range
+ trackFontScaleFactor.Value = fontTrackValue;
+ lblFontScaleValue.Text = $"{fontScaleFactor:F2}x ({(fontScaleFactor * 100 - 100):F1}% larger)";
+
+ // Enable/disable font scaling controls based on touchscreen support
+ bool touchscreenEnabled = settings.TouchscreenModeEnabled;
+ chkEnableFontScaling.Enabled = touchscreenEnabled;
+ bool fontScalingEnabled = touchscreenEnabled && settings.FontScalingEnabled;
+ trackFontScaleFactor.Enabled = fontScalingEnabled;
+ lblFontScaleFactor.Enabled = touchscreenEnabled;
+ lblFontScaleValue.Enabled = touchscreenEnabled;
+ }
+ finally
+ {
+ _updatingFromEvent = false;
+ }
+ }
+
+ private void UpdateStatus()
+ {
+ var settings = KryptonManager.TouchscreenSettingsValues;
+ bool isEnabled = settings.TouchscreenModeEnabled;
+ float controlScaleFactor = KryptonManager.TouchscreenScaleFactor;
+ bool fontScalingEnabled = settings.FontScalingEnabled && isEnabled;
+ float fontScaleFactor = KryptonManager.TouchscreenFontScaleFactor;
+
+ string statusText;
+ if (isEnabled)
+ {
+ statusText = $"Touchscreen Support: ENABLED - Control Scale: {controlScaleFactor:F2}x ({(controlScaleFactor * 100 - 100):F1}% larger)";
+ if (fontScalingEnabled)
+ {
+ statusText += $" | Font Scale: {fontScaleFactor:F2}x ({(fontScaleFactor * 100 - 100):F1}% larger)";
+ }
+ else
+ {
+ statusText += " | Font Scaling: DISABLED";
+ }
+ }
+ else
+ {
+ statusText = $"Touchscreen Support: DISABLED - Controls at normal size";
+ }
+
+ lblStatus.Text = statusText;
+ lblStatus.StateCommon.ShortText.Color1 = isEnabled ? Color.Green : Color.Gray;
+
+ // Update button text
+ btnToggle.Text = isEnabled ? "Disable Touchscreen Support" : "Enable Touchscreen Support";
+ }
+
+ private void UpdateDpiInfo()
+ {
+ if (!IsHandleCreated) return;
+
+ IntPtr hWnd = Handle;
+
+ // Get primary monitor DPI (legacy method)
+ float dpiXPrimary = KryptonManager.GetDpiFactorX();
+ float dpiYPrimary = KryptonManager.GetDpiFactorY();
+ float dpiAvgPrimary = KryptonManager.GetDpiFactor();
+
+ // Get per-monitor DPI (window-aware method)
+ float dpiXPerMonitor = KryptonManager.GetDpiFactorX(hWnd);
+ float dpiYPerMonitor = KryptonManager.GetDpiFactorY(hWnd);
+ float dpiAvgPerMonitor = KryptonManager.GetDpiFactor(hWnd);
+
+ // Get combined scaling factors (DPI × Touchscreen)
+ float combinedXPrimary = KryptonManager.GetCombinedScaleFactorX();
+ float combinedYPrimary = KryptonManager.GetCombinedScaleFactorY();
+ float combinedAvgPrimary = KryptonManager.GetCombinedScaleFactor();
+
+ float combinedXPerMonitor = KryptonManager.GetCombinedScaleFactorX(hWnd);
+ float combinedYPerMonitor = KryptonManager.GetCombinedScaleFactorY(hWnd);
+ float combinedAvgPerMonitor = KryptonManager.GetCombinedScaleFactor(hWnd);
+
+ // Calculate actual DPI value from the per-monitor factor (DPI = factor * 96)
+ int actualDpi = (int)Math.Round(dpiAvgPerMonitor * 96f);
+
+ // Update DPI info labels
+ lblDpiPrimary.Text = $"Primary Monitor DPI: {dpiAvgPrimary:F2}x ({dpiXPrimary:F2}x, {dpiYPrimary:F2}y)";
+ lblDpiPerMonitor.Text = $"Per-Monitor DPI: {dpiAvgPerMonitor:F2}x ({dpiXPerMonitor:F2}x, {dpiYPerMonitor:F2}y)";
+
+ // Display the calculated DPI value
+ lblDpiActual.Text = $"Calculated DPI: {actualDpi} ({dpiAvgPerMonitor:F2}x)";
+ lblDpiActual.StateCommon.ShortText.Color1 = Color.Blue;
+
+ // Update combined scaling info
+ lblCombinedPrimary.Text = $"Combined (Primary): {combinedAvgPrimary:F2}x ({combinedXPrimary:F2}x, {combinedYPrimary:F2}y)";
+ lblCombinedPerMonitor.Text = $"Combined (Per-Monitor): {combinedAvgPerMonitor:F2}x ({combinedXPerMonitor:F2}x, {combinedYPerMonitor:F2}y)";
+
+ // Highlight if there's a difference (multi-monitor scenario)
+ if (Math.Abs(dpiAvgPrimary - dpiAvgPerMonitor) > 0.01f)
+ {
+ lblDpiPerMonitor.StateCommon.ShortText.Color1 = Color.Orange;
+ lblCombinedPerMonitor.StateCommon.ShortText.Color1 = Color.Orange;
+ lblDpiWarning.Text = "⚠ Multi-monitor detected: Per-monitor DPI differs from primary monitor";
+ lblDpiWarning.StateCommon.ShortText.Color1 = Color.Orange;
+ }
+ else
+ {
+ lblDpiPerMonitor.StateCommon.ShortText.Color1 = Color.Black;
+ lblCombinedPerMonitor.StateCommon.ShortText.Color1 = Color.Black;
+ lblDpiWarning.Text = "✓ Single monitor or matching DPI";
+ lblDpiWarning.StateCommon.ShortText.Color1 = Color.Green;
+ }
+
+ // Show scaling example
+ int baseSize = 100;
+ int scaledByDpi = KryptonManager.ScaleValueByDpi(baseSize);
+ int scaledByBoth = KryptonManager.ScaleValueByDpiAndTouchscreen(baseSize);
+ int scaledByBothPerMonitor = (int)Math.Round(baseSize * combinedAvgPerMonitor);
+
+ lblScalingExample.Text = $"Scaling Example (base={baseSize}px): DPI only={scaledByDpi}px, DPI+Touchscreen={scaledByBoth}px, Per-Monitor={scaledByBothPerMonitor}px";
+ }
+}
diff --git a/Source/Krypton Components/TestForm/TouchscreenSupportTest.cs b/Source/Krypton Components/TestForm/TouchscreenSupportTest.cs
index a5f2e795d..d7581050c 100644
--- a/Source/Krypton Components/TestForm/TouchscreenSupportTest.cs
+++ b/Source/Krypton Components/TestForm/TouchscreenSupportTest.cs
@@ -55,6 +55,11 @@ private void InitializeForm()
// Update status
UpdateStatus();
+
+ // Add DPI cache invalidation on form resize/move to handle monitor changes
+ Resize += (s, e) => KryptonManager.InvalidateDpiCache();
+
+ Move += (s, e) => KryptonManager.InvalidateDpiCache();
}
private void SetupDemoControls()
@@ -370,6 +375,14 @@ private void UpdateStatus()
bool autoDetect = settings.AutomaticallyDetectTouchscreen;
bool isAvailable = KryptonManager.IsTouchscreenAvailable();
+ // Get DPI information
+ float dpiX = KryptonManager.GetDpiFactorX();
+ float dpiY = KryptonManager.GetDpiFactorY();
+ float dpiAvg = KryptonManager.GetDpiFactor();
+ float combinedX = KryptonManager.GetCombinedScaleFactorX();
+ float combinedY = KryptonManager.GetCombinedScaleFactorY();
+ float combinedAvg = KryptonManager.GetCombinedScaleFactor();
+
string statusText;
if (isEnabled)
{
@@ -382,10 +395,13 @@ private void UpdateStatus()
{
statusText += " | Font Scaling: DISABLED";
}
+
+ // Add DPI and combined scaling info
+ statusText += $" | DPI: {dpiAvg:F2}x ({dpiX:F2}x, {dpiY:F2}y) | Combined: {combinedAvg:F2}x ({combinedX:F2}x, {combinedY:F2}y)";
}
else
{
- statusText = "Touchscreen Support: DISABLED - Controls at normal size";
+ statusText = $"Touchscreen Support: DISABLED - Controls at normal size | DPI: {dpiAvg:F2}x ({dpiX:F2}x, {dpiY:F2}y)";
}
if (autoDetect)
@@ -405,6 +421,59 @@ private void UpdateStatus()
btnToggle.Text = isEnabled ? "Disable Touchscreen Support" : "Enable Touchscreen Support";
}
+ ///
+ /// Demonstrates the DPI-aware helper methods available in KryptonManager.
+ /// This method shows examples of how to use the scaling helpers for various types.
+ ///
+ private void DemonstrateDpiHelperMethods()
+ {
+ // Example 1: Get DPI factors
+ float dpiX = KryptonManager.GetDpiFactorX();
+ float dpiY = KryptonManager.GetDpiFactorY();
+ float dpiAvg = KryptonManager.GetDpiFactor();
+
+ // Example 2: Get combined scaling (DPI × Touchscreen)
+ float combinedX = KryptonManager.GetCombinedScaleFactorX();
+ float combinedY = KryptonManager.GetCombinedScaleFactorY();
+ float combinedAvg = KryptonManager.GetCombinedScaleFactor();
+
+ // Example 3: Scale a single value by DPI
+ int baseSize = 100;
+ int scaledByDpi = KryptonManager.ScaleValueByDpi(baseSize);
+ float scaledByDpiFloat = KryptonManager.ScaleValueByDpi(100f);
+
+ // Example 4: Scale a value by combined DPI and touchscreen
+ int scaledByBoth = KryptonManager.ScaleValueByDpiAndTouchscreen(baseSize);
+ float scaledByBothFloat = KryptonManager.ScaleValueByDpiAndTouchscreen(100f);
+
+ // Example 5: Scale a Size
+ Size baseSizeObj = new Size(200, 100);
+ Size scaledByDpiSize = KryptonManager.ScaleSizeByDpi(baseSizeObj);
+ Size scaledByBothSize = KryptonManager.ScaleSizeByDpiAndTouchscreen(baseSizeObj);
+
+ // Example 6: Scale a Point
+ Point basePoint = new Point(50, 75);
+ Point scaledByDpiPoint = KryptonManager.ScalePointByDpi(basePoint);
+ Point scaledByBothPoint = KryptonManager.ScalePointByDpiAndTouchscreen(basePoint);
+
+ // Example 7: Scale a Rectangle
+ Rectangle baseRect = new Rectangle(10, 20, 200, 100);
+ Rectangle scaledByDpiRect = KryptonManager.ScaleRectangleByDpi(baseRect);
+ Rectangle scaledByBothRect = KryptonManager.ScaleRectangleByDpiAndTouchscreen(baseRect);
+
+ // Example 8: Invalidate DPI cache when moving to a different monitor
+ // KryptonManager.InvalidateDpiCache(); // Call this when DPI changes
+
+ // Display results (for demonstration purposes)
+ string message = $"DPI Helper Methods Demo:\n\n" +
+ $"DPI Factors: X={dpiX:F2}, Y={dpiY:F2}, Avg={dpiAvg:F2}\n" +
+ $"Combined Factors: X={combinedX:F2}, Y={combinedY:F2}, Avg={combinedAvg:F2}\n\n" +
+ $"Base Size: {baseSize} → Scaled by DPI: {scaledByDpi}, Scaled by Both: {scaledByBoth}\n" +
+ $"Base Size Object: {baseSizeObj} → Scaled by DPI: {scaledByDpiSize}, Scaled by Both: {scaledByBothSize}\n" +
+ $"Base Point: {basePoint} → Scaled by DPI: {scaledByDpiPoint}, Scaled by Both: {scaledByBothPoint}\n" +
+ $"Base Rectangle: {baseRect} → Scaled by DPI: {scaledByDpiRect}, Scaled by Both: {scaledByBothRect}";
+
+ KryptonMessageBox.Show(message, "DPI Helper Methods Demo", KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Information);
private void ChkAutoDetect_CheckedChanged(object? sender, EventArgs e)
{
if (_updatingFromEvent) return;