diff --git a/src/User32/PublicAPI.Unshipped.txt b/src/User32/PublicAPI.Unshipped.txt
index 28fdaf0f..4fc61cca 100644
--- a/src/User32/PublicAPI.Unshipped.txt
+++ b/src/User32/PublicAPI.Unshipped.txt
@@ -1,3 +1,21 @@
+PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.DCDC_DEFAULT = 0 -> PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.DCDC_DISABLE_FONT_UPDATE = 1 -> PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.DCDC_DISABLE_RELAYOUT = 2 -> PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS.DDC_DEFAULT = 0 -> PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS.DDC_DISABLE_ALL = 1 -> PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS.DDC_DISABLE_CONTROL_RELAYOUT = PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS.DDC_DISABLE_ALL | PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS.DDC_DISABLE_RESIZE -> PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS.DDC_DISABLE_RESIZE = 2 -> PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS
+PInvoke.User32.DPI_AWARENESS
+PInvoke.User32.DPI_AWARENESS.DPI_AWARENESS_INVALID = -1 -> PInvoke.User32.DPI_AWARENESS
+PInvoke.User32.DPI_AWARENESS.DPI_AWARENESS_PER_MONITOR_AWARE = 2 -> PInvoke.User32.DPI_AWARENESS
+PInvoke.User32.DPI_AWARENESS.DPI_AWARENESS_SYSTEM_AWARE = 1 -> PInvoke.User32.DPI_AWARENESS
+PInvoke.User32.DPI_AWARENESS.DPI_AWARENESS_UNAWARE = 0 -> PInvoke.User32.DPI_AWARENESS
+PInvoke.User32.DPI_HOSTING_BEHAVIOR
+PInvoke.User32.DPI_HOSTING_BEHAVIOR.DPI_HOSTING_BEHAVIOR_DEFAULT = 0 -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
+PInvoke.User32.DPI_HOSTING_BEHAVIOR.DPI_HOSTING_BEHAVIOR_INVALID = -1 -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
+PInvoke.User32.DPI_HOSTING_BEHAVIOR.DPI_HOSTING_BEHAVIOR_MIXED = 1 -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
PInvoke.User32.GetNextWindowCommands
PInvoke.User32.GetNextWindowCommands.GW_HWNDNEXT = 2 -> PInvoke.User32.GetNextWindowCommands
PInvoke.User32.GetNextWindowCommands.GW_HWNDPREV = 3 -> PInvoke.User32.GetNextWindowCommands
@@ -15,6 +33,9 @@ PInvoke.User32.SendMessageTimeoutFlags.SMTO_BLOCK = 1 -> PInvoke.User32.SendMess
PInvoke.User32.SendMessageTimeoutFlags.SMTO_ERRORONEXIT = 32 -> PInvoke.User32.SendMessageTimeoutFlags
PInvoke.User32.SendMessageTimeoutFlags.SMTO_NORMAL = 0 -> PInvoke.User32.SendMessageTimeoutFlags
PInvoke.User32.SendMessageTimeoutFlags.SMTO_NOTIMEOUTIFNOTHUNG = 8 -> PInvoke.User32.SendMessageTimeoutFlags
+PInvoke.User32.WindowMessage.WM_DPICHANGED_AFTERPARENT = 739 -> PInvoke.User32.WindowMessage
+PInvoke.User32.WindowMessage.WM_DPICHANGED_BEFOREPARENT = 738 -> PInvoke.User32.WindowMessage
+PInvoke.User32.WindowMessage.WM_GETDPISCALEDSIZE = 740 -> PInvoke.User32.WindowMessage
PInvoke.User32.mouse_eventFlags
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_ABSOLUTE = 32768 -> PInvoke.User32.mouse_eventFlags
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_HWHEEL = 4096 -> PInvoke.User32.mouse_eventFlags
@@ -28,14 +49,42 @@ PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_RIGHTUP = 16 -> PInvoke.User32.mouse
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_WHEEL = 2048 -> PInvoke.User32.mouse_eventFlags
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_XDOWN = 128 -> PInvoke.User32.mouse_eventFlags
PInvoke.User32.mouse_eventFlags.MOUSEEVENTF_XUP = 256 -> PInvoke.User32.mouse_eventFlags
+static PInvoke.User32.AdjustWindowRectExForDpi(System.IntPtr lpRect, PInvoke.User32.WindowStyles dwStyle, bool bMenu, PInvoke.User32.WindowStylesEx dwExStyle, int dpi) -> bool
static PInvoke.User32.CreateWindowEx(PInvoke.User32.WindowStylesEx dwExStyle, short lpClassName, string lpWindowName, PInvoke.User32.WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, System.IntPtr hWndParent, System.IntPtr hMenu, System.IntPtr hInstance, System.IntPtr lpParam) -> System.IntPtr
static PInvoke.User32.CreateWindowEx(PInvoke.User32.WindowStylesEx dwExStyle, short lpClassName, string lpWindowName, PInvoke.User32.WindowStyles dwStyle, int x, int y, int nWidth, int nHeight, System.IntPtr hWndParent, System.IntPtr hMenu, System.IntPtr hInstance, void* lpParam) -> System.IntPtr
static PInvoke.User32.GetNextWindow(System.IntPtr hWnd, PInvoke.User32.GetNextWindowCommands wCmd) -> System.IntPtr
+static PInvoke.User32.SystemParametersInfoForDpi(PInvoke.User32.SystemParametersInfoAction uiAction, int uiParam, System.IntPtr pvParam, PInvoke.User32.SystemParametersInfoFlags fWinIni, int dpi) -> bool
static PInvoke.User32.mouse_event(PInvoke.User32.mouse_eventFlags dwFlags, int dx, int dy, int dwData, System.IntPtr dwExtraInfo) -> void
+static extern PInvoke.User32.AdjustWindowRectExForDpi(PInvoke.RECT* lpRect, PInvoke.User32.WindowStyles dwStyle, bool bMenu, PInvoke.User32.WindowStylesEx dwExStyle, int dpi) -> bool
+static extern PInvoke.User32.AreDpiAwarenessContextsEqual(System.IntPtr dpiContextA, System.IntPtr dpiContextB) -> bool
static extern PInvoke.User32.DestroyWindow(System.IntPtr hWnd) -> bool
+static extern PInvoke.User32.EnableNonClientDpiScaling(System.IntPtr hwnd) -> bool
+static extern PInvoke.User32.GetAwarenessFromDpiAwarenessContext(System.IntPtr dpiAwarenessContext) -> PInvoke.User32.DPI_AWARENESS
+static extern PInvoke.User32.GetDialogControlDpiChangeBehavior(System.IntPtr hWnd) -> PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS
+static extern PInvoke.User32.GetDialogDpiChangeBehavior(System.IntPtr hDlg) -> PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS
+static extern PInvoke.User32.GetDpiForSystem() -> int
+static extern PInvoke.User32.GetDpiForWindow(System.IntPtr hwnd) -> int
+static extern PInvoke.User32.GetDpiFromDpiAwarenessContext(System.IntPtr dpiAwarenessContext) -> int
+static extern PInvoke.User32.GetSystemDpiForProcess(PInvoke.Kernel32.SafeObjectHandle hProcess) -> int
+static extern PInvoke.User32.GetSystemMetricsForDpi(int nIndex, int dpi) -> bool
+static extern PInvoke.User32.GetThreadDpiAwarenessContext() -> System.IntPtr
+static extern PInvoke.User32.GetThreadDpiHostingBehavior() -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
static extern PInvoke.User32.GetTopWindow(System.IntPtr hWnd) -> System.IntPtr
static extern PInvoke.User32.GetWindow(System.IntPtr hWnd, PInvoke.User32.GetWindowCommands wCmd) -> System.IntPtr
+static extern PInvoke.User32.GetWindowDpiAwarenessContext(System.IntPtr hwnd) -> System.IntPtr
+static extern PInvoke.User32.GetWindowDpiHostingBehavior(System.IntPtr hwnd) -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
+static extern PInvoke.User32.IsValidDpiAwarenessContext(System.IntPtr dpiAwarenessContext) -> bool
static extern PInvoke.User32.SendMessageTimeout(System.IntPtr hWnd, PInvoke.User32.WindowMessage msg, System.IntPtr wParam, System.IntPtr lParam, PInvoke.User32.SendMessageTimeoutFlags flags, int timeout, out System.IntPtr pdwResult) -> System.IntPtr
+static extern PInvoke.User32.SetDialogControlDpiChangeBehavior(System.IntPtr hwnd, PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS mask, PInvoke.User32.DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS values) -> bool
+static extern PInvoke.User32.SetDialogDpiChangeBehavior(System.IntPtr hDlg, PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS mask, PInvoke.User32.DIALOG_DPI_CHANGE_BEHAVIORS values) -> bool
static extern PInvoke.User32.SetLastErrorEx(uint dwErrCode, uint dwType) -> void
+static extern PInvoke.User32.SetProcessDpiAwarenessContext(System.IntPtr dpiAWarenessContext) -> bool
+static extern PInvoke.User32.SetThreadDpiAwarenessContext(System.IntPtr dpiContext) -> System.IntPtr
+static extern PInvoke.User32.SetThreadDpiHostingBehavior(PInvoke.User32.DPI_HOSTING_BEHAVIOR dpiHostingBehavior) -> PInvoke.User32.DPI_HOSTING_BEHAVIOR
static extern PInvoke.User32.SetWindowText(System.IntPtr hWnd, string lpString) -> bool
-static extern PInvoke.User32.mouse_event(PInvoke.User32.mouse_eventFlags dwFlags, int dx, int dy, int dwData, void* dwExtraInfo) -> void
\ No newline at end of file
+static extern PInvoke.User32.SystemParametersInfoForDpi(PInvoke.User32.SystemParametersInfoAction uiAction, int uiParam, void* pvParam, PInvoke.User32.SystemParametersInfoFlags fWinIni, int dpi) -> bool
+static extern PInvoke.User32.mouse_event(PInvoke.User32.mouse_eventFlags dwFlags, int dx, int dy, int dwData, void* dwExtraInfo) -> void
+static readonly PInvoke.User32.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE -> System.IntPtr
+static readonly PInvoke.User32.DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 -> System.IntPtr
+static readonly PInvoke.User32.DPI_AWARENESS_CONTEXT_SYSTEM_AWARE -> System.IntPtr
+static readonly PInvoke.User32.DPI_AWARENESS_CONTEXT_UNAWARE -> System.IntPtr
\ No newline at end of file
diff --git a/src/User32/User32+DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.cs b/src/User32/User32+DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.cs
new file mode 100644
index 00000000..01408a65
--- /dev/null
+++ b/src/User32/User32+DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS.cs
@@ -0,0 +1,40 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace PInvoke
+{
+ using System;
+
+ ///
+ /// Contains nested type
+ ///
+ public partial class User32
+ {
+ ///
+ /// Describes per-monitor DPI scaling behavior overrides for child windows within dialogs. The values in this enumeration are bitfields and can be combined.
+ ///
+ ///
+ /// This enum is used with SetDialogControlDpiChangeBehavior in order to override the default per-monitor DPI scaling behavior for a child window within a dialog.
+ ///
+ /// These settings only apply to individual controls within dialogs. The dialog-wide per-monitor DPI scaling behavior of a dialog is controlled by .
+ ///
+ [Flags]
+ public enum DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS : int
+ {
+ ///
+ /// The default behavior of the dialog manager. The dialog managed will update the font, size, and position of the child window on DPI changes.
+ ///
+ DCDC_DEFAULT = 0x0000,
+
+ ///
+ /// Prevents the dialog manager from sending an updated font to the child window via WM_SETFONT in response to a DPI change.
+ ///
+ DCDC_DISABLE_FONT_UPDATE = 0x0001,
+
+ ///
+ /// Prevents the dialog manager from resizing and repositioning the child window in response to a DPI change.
+ ///
+ DCDC_DISABLE_RELAYOUT = 0x0002,
+ }
+ }
+}
diff --git a/src/User32/User32+DIALOG_DPI_CHANGE_BEHAVIORS.cs b/src/User32/User32+DIALOG_DPI_CHANGE_BEHAVIORS.cs
new file mode 100644
index 00000000..8c8174eb
--- /dev/null
+++ b/src/User32/User32+DIALOG_DPI_CHANGE_BEHAVIORS.cs
@@ -0,0 +1,42 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace PInvoke
+{
+ using System;
+
+ ///
+ /// Contains nested type
+ ///
+ public partial class User32
+ {
+ ///
+ /// In Per Monitor v2 contexts, dialogs will automatically respond to DPI changes by resizing themselves and re-computing the positions of their child windows (here referred to as re-layouting).
+ /// This enum works in conjunction with SetDialogDpiChangeBehavior in order to override the default DPI scaling behavior for dialogs.
+ /// This does not affect DPI scaling behavior for the child windows of dialogs(beyond re-layouting), which is controlled by .
+ ///
+ [Flags]
+ public enum DIALOG_DPI_CHANGE_BEHAVIORS : int
+ {
+ ///
+ /// The default behavior of the dialog manager. In response to a DPI change, the dialog manager will re-layout each control, update the font on each control, resize the dialog, and update the dialog's own font.
+ ///
+ DDC_DEFAULT = 0x0000,
+
+ ///
+ /// Prevents the dialog manager from responding to and , disabling all default DPI scaling behavior.
+ ///
+ DDC_DISABLE_ALL = 0x0001,
+
+ ///
+ /// Prevents the dialog manager from resizing the dialog in response to a DPI change.
+ ///
+ DDC_DISABLE_RESIZE = 0x0002,
+
+ ///
+ /// Prevents the dialog manager from re-layouting all of the dialogue's immediate children HWNDs in response to a DPI change.
+ ///
+ DDC_DISABLE_CONTROL_RELAYOUT = 0x0003,
+ }
+ }
+}
diff --git a/src/User32/User32+DPI_AWARENESS.cs b/src/User32/User32+DPI_AWARENESS.cs
new file mode 100644
index 00000000..9536945a
--- /dev/null
+++ b/src/User32/User32+DPI_AWARENESS.cs
@@ -0,0 +1,37 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace PInvoke
+{
+ ///
+ /// Contains the nested type.
+ ///
+ public partial class User32
+ {
+ ///
+ /// Identifies the dots per inch (dpi) setting for a thread, process, or window.
+ ///
+ public enum DPI_AWARENESS : int
+ {
+ ///
+ /// Invalid DPI awareness. This is an invalid DPI awareness value.
+ ///
+ DPI_AWARENESS_INVALID = -1,
+
+ ///
+ /// DPI unaware. This process does not scale for DPI changes and is always assumed to have a scale factor of 100% (96 DPI). It will be automatically scaled by the system on any other DPI setting.
+ ///
+ DPI_AWARENESS_UNAWARE = 0,
+
+ ///
+ /// System DPI aware. This process does not scale for DPI changes. It will query for the DPI once and use that value for the lifetime of the process. If the DPI changes, the process will not adjust to the new DPI value. It will be automatically scaled up or down by the system when the DPI changes from the system value.
+ ///
+ DPI_AWARENESS_SYSTEM_AWARE = 1,
+
+ ///
+ /// Per monitor DPI aware. This process checks for the DPI when it is created and adjusts the scale factor whenever the DPI changes. These processes are not automatically scaled by the system.
+ ///
+ DPI_AWARENESS_PER_MONITOR_AWARE = 2,
+ }
+ }
+}
diff --git a/src/User32/User32+DPI_HOSTING_BEHAVIOR.cs b/src/User32/User32+DPI_HOSTING_BEHAVIOR.cs
new file mode 100644
index 00000000..724a45aa
--- /dev/null
+++ b/src/User32/User32+DPI_HOSTING_BEHAVIOR.cs
@@ -0,0 +1,32 @@
+// Copyright (c) All contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace PInvoke
+{
+ ///
+ /// Contains nested type
+ ///
+ public partial class User32
+ {
+ ///
+ /// Identifies the DPI hosting behavior for a window. This behavior allows windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT.
+ ///
+ public enum DPI_HOSTING_BEHAVIOR : int
+ {
+ ///
+ /// Invalid DPI hosting behavior. This usually occurs if the previous call used an invalid parameter.
+ ///
+ DPI_HOSTING_BEHAVIOR_INVALID = -1,
+
+ ///
+ /// Default DPI hosting behavior. The associated window behaves as normal, and cannot create or re-parent child windows with a different DPI_AWARENESS_CONTEXT.
+ ///
+ DPI_HOSTING_BEHAVIOR_DEFAULT = 0,
+
+ ///
+ /// Mixed DPI hosting behavior. This enables the creation and re-parenting of child windows with different DPI_AWARENESS_CONTEXT. These child windows will be independently scaled by the OS.
+ ///
+ DPI_HOSTING_BEHAVIOR_MIXED = 1,
+ }
+ }
+}
diff --git a/src/User32/User32+WindowMessage.cs b/src/User32/User32+WindowMessage.cs
index 89ecfb55..f7893e37 100644
--- a/src/User32/User32+WindowMessage.cs
+++ b/src/User32/User32+WindowMessage.cs
@@ -982,6 +982,21 @@ public enum WindowMessage : int
///
WM_DPICHANGED = 0x02E0,
+ ///
+ /// For Per Monitor v2 top-level windows, this message is sent to all HWNDs in the child HWDN tree of the window that is undergoing a DPI change. This message occurs before the top-level window receives , and traverses the child tree from the bottom up.
+ ///
+ WM_DPICHANGED_BEFOREPARENT = 0x02E2,
+
+ ///
+ /// For Per Monitor v2 top-level windows, this message is sent to all HWNDs in the child HWDN tree of the window that is undergoing a DPI change. This message occurs after the top-level window receives , and traverses the child tree from the top down.
+ ///
+ WM_DPICHANGED_AFTERPARENT = 0x02E3,
+
+ ///
+ /// The WM_GETDPISCALEDSIZE message tells the operating system that the window will be sized to dimensions other than the default.
+ ///
+ WM_GETDPISCALEDSIZE = 0x02E4,
+
///
/// An application sends a WM_CUT message to an edit control or combo box to delete (cut) the current selection, if any, in the edit control and copy the deleted text to the clipboard in CF_TEXT format.
///
diff --git a/src/User32/User32.cs b/src/User32/User32.cs
index d78d04db..b06580a5 100644
--- a/src/User32/User32.cs
+++ b/src/User32/User32.cs
@@ -11,7 +11,7 @@ namespace PInvoke
using PInvoke;
using static PInvoke.Kernel32;
- #pragma warning disable SA1300 // Elements must begin with an uppercase letter
+#pragma warning disable SA1300 // Elements must begin with an uppercase letter
///
/// Exported functions from the User32.dll Windows library.
@@ -78,6 +78,49 @@ public static partial class User32
/// Windows icon or the icon of the window specified in .
public static readonly IntPtr HBMMENU_SYSTEM = new IntPtr(1);
+ ///
+ /// Gets the predefined DPI_AWARENESS_CONTEXT handle for DPI unaware mode. These windows do not scale
+ /// for DPI changes and are always assumed to have a scale factor of 100% (96 DPI). They will be automatically scaled by
+ /// the system on any other DPI setting.
+ ///
+ /// DPI_AWARENESS_CONTEXT values should never be compared directly. Instead, use AreDpiAwarenessContextsEqual function
+ public static readonly IntPtr DPI_AWARENESS_CONTEXT_UNAWARE = new IntPtr(-1);
+
+ ///
+ /// Gets the predefined DPI_AWARENESS_CONTEXT handle for System aware mode. These windows do not scale for DPI changes.
+ /// They will query for the DPI once and use that value for the lifetime of the process. If the DPI changes,
+ /// the process will not adjust to the new DPI value. It will be automatically scaled up or down by the system
+ /// when the DPI changes from the system value.
+ ///
+ /// DPI_AWARENESS_CONTEXT values should never be compared directly. Instead, use AreDpiAwarenessContextsEqual function
+ public static readonly IntPtr DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = new IntPtr(-2);
+
+ ///
+ /// Gets the predefined DPI_AWARENESS_CONTEXT handle for the Per Monitor mode. These windows check for the DPI when
+ /// they are created and adjust the scale factor whenever the DPI changes. These processes are not automatically
+ /// scaled by the system.
+ ///
+ /// DPI_AWARENESS_CONTEXT values should never be compared directly. Instead, use AreDpiAwarenessContextsEqual function
+ public static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = new IntPtr(-3);
+
+ ///
+ /// Gets the predefined DPI_AWARENESS_CONTEXT handle for Per Monitor v2 mode.
+ /// Per Monitor v2 is an advancement over the original Per Monitor DPI awareness mode, which enables applications to access
+ /// new DPI-related scaling behaviors on a per top-level window basis. Per Monitor v2 was made available in the
+ /// Creators Update of Windows 10, and is not available on earlier versions of the operating system. The additional behaviors
+ /// introduced are as follows:
+ ///
+ /// - Child window DPI change notifications - In Per Monitor v2 contexts, the entire window tree is notified of any DPI changes that occur.
+ /// - Scaling of non-client area - All windows will automatically have their non-client area drawn in a DPI sensitive fashion. Calls to EnableNonClientDpiScaling are unnecessary.
+ /// - Scaling of Win32 menus - All NTUSER menus created in Per Monitor v2 contexts will be scaling in a per-monitor fashion.
+ /// - Dialog Scaling - Win32 dialogs created in Per Monitor v2 contexts will automatically respond to DPI changes.
+ /// - Improved scaling of comctl32 controls - Various comctl32 controls have improved DPI scaling behavior in Per Monitor v2 contexts.
+ /// - Improved theming behavior - UxTheme handles opened in the context of a Per Monitor v2 window will operate in terms of the DPI associated with that window.
+ ///
+ ///
+ /// DPI_AWARENESS_CONTEXT values should never be compared directly. Instead, use AreDpiAwarenessContextsEqual function
+ public static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4);
+
///
/// A special windows handle used to indicate to
/// that the message is sent to all top-level windows in the system, including disabled or invisible unowned windows,
@@ -2921,6 +2964,362 @@ public static extern unsafe bool SetWindowPlacement(
[DllImport(nameof(User32))]
public static extern unsafe void mouse_event(mouse_eventFlags dwFlags, int dx, int dy, int dwData, void* dwExtraInfo);
+ ///
+ /// Calculates the required size of the window rectangle, based on the desired size of the client rectangle and the provided DPI. This window rectangle can then be passed to the CreateWindowEx function to create a window with a client area of the desired size.
+ ///
+ /// A pointer to a structure that contains the coordinates of the top-left and bottom-right corners of the desired client area. When the function returns, the structure contains the coordinates of the top-left and bottom-right corners of the window to accommodate the desired client area.
+ /// The Window Style of the window whose required size is to be calculated. Note that you cannot specify the style.
+ /// Indicates whether the window has a menu.
+ /// The Extended Window Style of the window whose required size is to be calculated.
+ /// The DPI to use for scaling.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern unsafe bool AdjustWindowRectExForDpi(
+ RECT* lpRect,
+ WindowStyles dwStyle,
+ [MarshalAs(UnmanagedType.Bool)] bool bMenu,
+ WindowStylesEx dwExStyle,
+ int dpi);
+
+ ///
+ /// Determines whether two DPI_AWARENESS_CONTEXT values are identical.
+ ///
+ /// The first value to compare.
+ /// The second value to compare.
+ /// Returns true if the values are equal, otherwise false.
+ ///
+ /// A DPI_AWARENESS_CONTEXT contains multiple pieces of information. For example, it includes both the current and the inherited values.
+ /// AreDpiAwarenessContextsEqual ignores informational flags and determines if the values are equal. You can't use a direct bitwise comparison because of these informational flags.
+ ///
+ [DllImport(nameof(User32))]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool AreDpiAwarenessContextsEqual(
+ IntPtr dpiContextA,
+ IntPtr dpiContextB);
+
+ ///
+ /// In high-DPI displays, enables automatic display scaling of the non-client area portions of the specified top-level window. Must be called during the initialization of that window.
+ ///
+ /// The window that should have automatic scaling enabled.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool EnableNonClientDpiScaling(
+ IntPtr hwnd);
+
+ ///
+ /// Retrieves the value from a DPI_AWARENESS_CONTEXT.
+ ///
+ /// The DPI_AWARENESS_CONTEXT you want to examine.
+ /// The . If the provided is null or invalid, this method will return .
+ [DllImport(nameof(User32))]
+ public static extern DPI_AWARENESS GetAwarenessFromDpiAwarenessContext(
+ IntPtr dpiAwarenessContext);
+
+ ///
+ /// Returns the system DPI.
+ ///
+ /// The system DPI value.
+ ///
+ /// The return value will be dependent based upon the calling context. If the current thread has a value of , the return value will be 96. That is because the current context always assumes a DPI of 96. For any other value, the return value will be the actual system DPI.
+ /// You should not cache the system DPI, but should use GetDpiForSystem whenever you need the system DPI value.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern int GetDpiForSystem();
+
+ ///
+ /// Returns the dots per inch (dpi) value for the associated window.
+ ///
+ /// The window you want to get information about.
+ /// The DPI for the window which depends on the of the window. An invalid value will result in a return value of 0.
+ ///
+ /// The following table indicates the return value of GetDpiForWindow based on the of the provided .
+ /// +---------------------------------+-----------------------------------------------------+
+ /// | DPI_AWARENESS | Return value |
+ /// +---------------------------------+-----------------------------------------------------+
+ /// | DPI_AWARENESS_UNAWARE | 96 |
+ /// | DPI_AWARENESS_SYSTEM_AWARE | The system DPI. |
+ /// | DPI_AWARENESS_PER_MONITOR_AWARE | The DPI of the monitor where the window is located. |
+ /// +---------------------------------+-----------------------------------------------------+
+ ///
+ [DllImport(nameof(User32))]
+ public static extern int GetDpiForWindow(
+ IntPtr hwnd);
+
+ ///
+ /// Retrieves the specified system metric or system configuration setting taking into account a provided DPI.
+ ///
+ /// The system metric or configuration setting to be retrieved. See for the possible values.
+ /// The DPI to use for scaling the metric.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ /// This function returns the same result as but scales it according to an arbitrary DPI you provide if appropriate.
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool GetSystemMetricsForDpi(
+ int nIndex,
+ int dpi);
+
+ ///
+ /// Gets the DPI_AWARENESS_CONTEXT for the current thread.
+ ///
+ /// The current DPI_AWARENESS_CONTEXT for the thread.
+ ///
+ /// This method will return the latest DPI_AWARENESS_CONTEXT sent to SetThreadDpiAwarenessContext. If SetThreadDpiAwarenessContext was never called for this thread, then the return value will equal the default DPI_AWARENESS_CONTEXT for the process.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern IntPtr GetThreadDpiAwarenessContext();
+
+ ///
+ /// Returns the DPI_AWARENESS_CONTEXT associated with a window.
+ ///
+ /// The window to query.
+ /// The DPI_AWARENESS_CONTEXT for the provided window. If the window is not valid, the return value is NULL.
+ ///
+ /// The return value of GetWindowDpiAwarenessContext is not affected by the of the current thread. It only indicates the context of the window specified by the input parameter.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern IntPtr GetWindowDpiAwarenessContext(
+ IntPtr hwnd);
+
+ ///
+ /// Determines if a specified DPI_AWARENESS_CONTEXT is valid and supported by the current system.
+ ///
+ /// The context that you want to determine if it is supported.
+ /// true if the provided context is supported, otherwise false.
+ ///
+ /// IsValidDpiAwarenessContext determines the validity of any provided DPI_AWARENESS_CONTEXT. You should make sure a context is valid before using SetThreadDpiAwarenessContext to that context.
+ /// An input value of NULL is considered to be an invalid context and will result in a return value of false.
+ ///
+ [DllImport(nameof(User32))]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool IsValidDpiAwarenessContext(
+ IntPtr dpiAwarenessContext);
+
+ ///
+ /// Set the DPI awareness for the current thread to the provided value.
+ ///
+ /// The new DPI_AWARENESS_CONTEXT for the current thread. This context includes the value.
+ /// The old DPI_AWARENESS_CONTEXT for the thread. If the is invalid, the thread will not be updated and the return value will be NULL. You can use this value to restore the old DPI_AWARENESS_CONTEXT after overriding it with a predefined value.
+ [DllImport(nameof(User32))]
+ public static extern IntPtr SetThreadDpiAwarenessContext(
+ IntPtr dpiContext);
+
+ ///
+ /// Retrieves the value of one of the system-wide parameters, taking into account the provided DPI value.
+ ///
+ /// The system-wide parameter to be retrieved. This function is only intended for use with , , or . See for more information on these values.
+ /// A parameter whose usage and format depends on the system parameter being queried. For more information about system-wide parameters, see the parameter. If not otherwise indicated, you must specify zero for this parameter.
+ /// A parameter whose usage and format depends on the system parameter being queried. For more information about system-wide parameters, see the parameter. If not otherwise indicated, you must specify NULL for this parameter.
+ /// Has no effect for with this API. This parameter only has an effect if you're setting parameter.
+ /// The DPI to use for scaling the metric.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ ///
+ /// This function returns a similar result as SystemParametersInfo, but scales it according to an arbitrary DPI you provide (if appropriate). It only scales with the following possible values for uiAction:
+ /// SPI_GETICONTITLELOGFONT, SPI_GETICONMETRICS, SPI_GETNONCLIENTMETRICS.
+ /// Other possible uiAction values do not provide ForDPI behavior, and therefore this function returns 0 if called with them.
+ /// For uiAction values that contain strings within their associated structures, only Unicode(LOGFONTW) strings are supported in this function.
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static unsafe extern bool SystemParametersInfoForDpi(
+ SystemParametersInfoAction uiAction,
+ int uiParam,
+ void* pvParam,
+ SystemParametersInfoFlags fWinIni,
+ int dpi);
+
+ ///
+ /// Sets the current process to a specified dots per inch (dpi) awareness context.
+ ///
+ /// The DPI awareness value to set.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ /// Possible errors are for an invalid input, and if the default API awareness mode for the process has already been set (via a previous API call or within the application manifest).
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetProcessDpiAwarenessContext(
+ IntPtr dpiAWarenessContext);
+
+ ///
+ /// Dialogs in Per-Monitor v2 contexts are automatically DPI scaled. This method lets you customize their DPI change behavior.
+ /// This function works in conjunction with the enum in order to override the default DPI scaling behavior for
+ /// dialogs.This function is called on a specified dialog, for which the specified flags are individually saved.
+ /// This function does not affect the DPI scaling behavior for the child windows of the dialog in question - that is done with SetDialogControlDpiChangeBehavior.
+ ///
+ /// A handle for the dialog whose behavior will be modified.
+ /// A mask specifying the subset of flags to be changed.
+ /// The desired value to be set for the specified subset of flags.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ /// Possible errors are for an invalid dialog HWND, and if if the dialog belongs to another process.
+ ///
+ ///
+ /// For extensibility, was modeled as a set of bit-flags representing separate behaviors. This function
+ /// follows the typical two-parameter approach to setting flags, where a mask specifies the subset of the flags to be changed.
+ /// It is not an error to call this API outside of Per Monitor v2 contexts, though the flags will have no effect on the behavior of the
+ /// specified dialog until the context is changed to Per Monitor v2.
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetDialogDpiChangeBehavior(
+ IntPtr hDlg,
+ DIALOG_DPI_CHANGE_BEHAVIORS mask,
+ DIALOG_DPI_CHANGE_BEHAVIORS values);
+
+ ///
+ /// Returns the flags that might have been set on a given dialog by an earlier call to SetDialogDpiChangeBehavior.
+ /// If that function was never called on the dialog, the return value will be 0.
+ ///
+ /// The handle for the dialog to examine.
+ /// The flags set on the given dialog. If passed an invalid handle, this function will return 0, and set its last error to .
+ ///
+ /// It can be difficult to distinguish between a return value of and the error case, which is zero. To determine between the two, it is recommended that you call to check the error.
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ public static extern DIALOG_DPI_CHANGE_BEHAVIORS GetDialogDpiChangeBehavior(
+ IntPtr hDlg);
+
+ ///
+ /// Overrides the default per-monitor DPI scaling behavior of a child window in a dialog.
+ ///
+ /// A handle for the window whose behavior will be modified.
+ /// A mask specifying the subset of flags to be changed.
+ /// The desired value to be set for the specified subset of flags.
+ ///
+ /// If the function succeeds, the return value is true.
+ /// If the function fails, the return value is false. To get extended error information, call .
+ ///
+ /// Possible errors are if passed an invalid HWND, and if the windows belongs to another process.
+ ///
+ ///
+ /// The behaviors are specified as values from the enum. This function follows the typical two-parameter approach
+ /// to setting flags, where a mask specifies the subset of the flags to be changed.
+ /// It is valid to set these behaviors on any window.It does not matter if the window is currently a child of a dialog at the point in time that SetDialogControlDpiChangeBehavior is
+ /// called.The behaviors are retained and will take effect only when the window is an immediate child of a dialog that has per-monitor DPI scaling enabled.
+ /// This API influences individual controls within dialogs.The dialog-wide per-monitor DPI scaling behavior is controlled by SetDialogDpiChangeBehavior.
+ ///
+ [DllImport(nameof(User32), SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool SetDialogControlDpiChangeBehavior(
+ IntPtr hwnd,
+ DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS mask,
+ DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS values);
+
+ ///
+ /// Retrieves and per-monitor DPI scaling behavior overrides of a child window in a dialog.
+ ///
+ /// The handle for the window to examine.
+ /// The flags set on the given window. If passed an invalid handle, this function will return zero, and set its last error to .
+ /// It can be difficult to distinguish between a return value of and the error case, which is zero. To determine between the two, it is recommended that you call to check the error.
+ [DllImport(nameof(User32), SetLastError = true)]
+ public static extern DIALOG_CONTROL_DPI_CHANGE_BEHAVIORS GetDialogControlDpiChangeBehavior(
+ IntPtr hWnd);
+
+ ///
+ /// Retrieves the system DPI associated with a given process. This is useful for avoiding compatibility issues that arise from sharing DPI-sensitive information between multiple system-aware processes with different system DPI values.
+ ///
+ /// The handle for the process to examine. If this value is null, this API behaves identically to .
+ /// The process's system DPI value.
+ ///
+ /// The return value will be dependent based upon the process passed as a parameter. If the specified process has a
+ /// value of , the return value will be 96. That is because the current context always assumes a DPI of 96.
+ /// For any other value, the return value will be the actual system DPI of the given process.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern int GetSystemDpiForProcess(
+ SafeObjectHandle hProcess);
+
+ ///
+ /// Retrieves the DPI from a given DPI_AWARENESS_CONTEXT handle. This enables you to determine the DPI of a thread without needed to examine a window created within that thread.
+ ///
+ /// The DPI_AWARENESS_CONTEXT handle to examine.
+ /// The DPI value associated with the DPI_AWARENESS_CONTEXT handle
+ ///
+ /// DPI_AWARENESS_CONTEXT handles associated with values of and
+ /// will return a value of 0 for their DPI. This is because the DPI of a
+ /// per-monitor-aware window can change, and the actual DPI cannot be returned without the window's HWND.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern int GetDpiFromDpiAwarenessContext(
+ IntPtr dpiAwarenessContext);
+
+ ///
+ /// Sets the thread's . This behavior allows windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT.
+ ///
+ /// The new value for the current thread.
+ ///
+ /// The previous for the thread. If the hosting behavior passed in is invalid, the thread will not be updated and the return value will be
+ /// . You can use this value to restore the old after overriding it with a predefined value.
+ ///
+ ///
+ ///
+ /// enables a mixed content hosting behavior, which allows parent windows created in the thread to host child windows with a different DPI_AWARENESS_CONTEXT value.
+ /// This property only effects new windows created within this thread while the mixed hosting behavior is active. A parent window with this hosting behavior is able to host child windows with
+ /// different DPI_AWARENESS_CONTEXT values, regardless of whether the child windows have mixed hosting behavior enabled
+ ///
+ ///
+ /// This hosting behavior does not allow for windows with per-monitor DPI_AWARENESS_CONTEXT values to be hosted until windows with DPI_AWARENESS_CONTEXT values of system or unaware.
+ ///
+ ///
+ /// To avoid unexpected outcomes, a thread's should be changed to support mixed hosting behaviors only when creating a new window which needs to support those behaviors.
+ /// Once that window is created, the hosting behavior should be switched back to its default value.
+ ///
+ ///
+ /// This API is used to change the thread's from its default value. This is only necessary if your app needs to host child windows from plugins and third-party
+ /// components that do not support per-monitor-aware context. This is most likely to occur if you are updating complex applications to support per-monitor DPI_AWARENESS_CONTEXT behaviors.
+ ///
+ ///
+ /// Enabling mixed hosting behavior will not automatically adjust the thread's DPI_AWARENESS_CONTEXT to be compatible with legacy content. The thread's awareness context must
+ /// still be manually changed before new windows are created to host such content.
+ ///
+ ///
+ [DllImport(nameof(User32))]
+ public static extern DPI_HOSTING_BEHAVIOR SetThreadDpiHostingBehavior(
+ DPI_HOSTING_BEHAVIOR dpiHostingBehavior);
+
+ ///
+ /// Retrieves the from the current thread.
+ ///
+ /// The of the current thread.
+ ///
+ /// This API returns the hosting behavior set by an earlier call of ,
+ /// or if no earlier call has been made.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern DPI_HOSTING_BEHAVIOR GetThreadDpiHostingBehavior();
+
+ ///
+ /// Returns the of the specified window.
+ ///
+ /// The handle for the window to examine.
+ /// The of the specified window.
+ ///
+ /// This API allows you to examine the hosting behavior of a window after it has been created. A window's hosting behavior
+ /// is the hosting behavior of the thread in which the window was created, as set by a call to .
+ /// This is a permanent value and cannot be changed after the window is created, even if the thread's hosting behavior is changed.
+ ///
+ [DllImport(nameof(User32))]
+ public static extern DPI_HOSTING_BEHAVIOR GetWindowDpiHostingBehavior(
+ IntPtr hwnd);
+
///
/// The BeginPaint function prepares the specified window for painting and fills a structure with information about the painting.
///
diff --git a/src/UxTheme/PublicAPI.Unshipped.txt b/src/UxTheme/PublicAPI.Unshipped.txt
index e69de29b..8ff50487 100644
--- a/src/UxTheme/PublicAPI.Unshipped.txt
+++ b/src/UxTheme/PublicAPI.Unshipped.txt
@@ -0,0 +1 @@
+static extern PInvoke.UxTheme.OpenThemeDataForDpi(System.IntPtr hwnd, string pszClassIdList, int dpi) -> PInvoke.UxTheme.SafeThemeHandle
\ No newline at end of file
diff --git a/src/UxTheme/UxTheme.cs b/src/UxTheme/UxTheme.cs
index 87ac0a79..fd52cf55 100644
--- a/src/UxTheme/UxTheme.cs
+++ b/src/UxTheme/UxTheme.cs
@@ -30,6 +30,33 @@ public static extern SafeThemeHandle OpenThemeData(
IntPtr hwnd,
string pszClassList);
+ ///
+ /// A variant of OpenThemeData that opens a theme handle associated with a specific DPI.
+ ///
+ /// The handle of the window for which theme data is required.
+ /// A pointer to a string that contains a semicolon-separated list of classes.
+ /// The specified DPI value with which to associate the theme handle. The function will return an error if this value is outside of those that correspond to the set of connected monitors.
+ /// See OpenThemeData
+ ///
+ ///
+ /// -
+ /// uxtheme!OpenThemeData will create theme handles associated with the DPI of a window when used with Per Monitor v2 windows. OpenThemeDataForDpi
+ /// allows you to open a theme handle for a specific DPI when you do not have a window at that DPI.
+ /// The behavior of the returned theme handle will be undermined if the requested DPI value does not correspond to a currently connected display.The theming system only loads theme assets
+ /// for the set of DPI values corresponding to the currently connected displays.
+ /// The theme handle will become invalid anytime the system reloads the theme data.Applications are required to monitor and close and reopen all
+ /// theme handles in response.This behavior is the same regardless of whether the handles were opened via OpenThemeData or OpenThemeDataForDpi.
+ ///
+ /// - The returned by this method is not the same one as those used within the UxTheme library, but it can be passed to
+ /// UxTheme API's seamlessly
+ ///
+ ///
+ [DllImport(nameof(User32), CharSet = CharSet.Unicode)]
+ public static extern SafeThemeHandle OpenThemeDataForDpi(
+ IntPtr hwnd,
+ [MarshalAs(UnmanagedType.LPWStr)] string pszClassIdList,
+ int dpi);
+
///
/// Retrieves the value of a property.
///