diff --git a/dnSpy/dnSpy.Contracts.DnSpy/Controls/Windows11RoundedCorners.cs b/dnSpy/dnSpy.Contracts.DnSpy/Controls/Windows11RoundedCorners.cs new file mode 100644 index 0000000000..d9643f0a66 --- /dev/null +++ b/dnSpy/dnSpy.Contracts.DnSpy/Controls/Windows11RoundedCorners.cs @@ -0,0 +1,62 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Interop; + +namespace dnSpy.Contracts.Controls { + /// + /// Rounded corner types + /// + public enum RoundedCornerType : uint { + /// + /// The default behavior. The system determines whether to enable rounded corners + /// + Default = 0, + /// + /// No rounded corners + /// + None = 1, + /// + /// Regular rounded corners + /// + Regular = 2, + /// + /// Small rounded corners + /// + Small = 3 + } + + /// + /// Enabled Windows 11 rounded corners for a or other supported control + /// + public sealed class Windows11RoundedCorners { + static readonly bool isWindows11 = Environment.OSVersion.Version is { Major: 10, Build: >= 22000 }; + +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + public static readonly DependencyProperty TypeProperty = DependencyProperty.RegisterAttached( + "Type", typeof(RoundedCornerType), typeof(Windows11RoundedCorners), new UIPropertyMetadata(RoundedCornerType.Default, TypePropertyChangedCallback)); + + public static void SetType(FrameworkElement element, RoundedCornerType value) => element.SetValue(TypeProperty, value); + public static RoundedCornerType GetType(FrameworkElement element) => (RoundedCornerType)element.GetValue(TypeProperty); +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + + static void TypePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { + if (!isWindows11 || d is not IInputElement inputElement) + return; + PresentationSource.AddSourceChangedHandler(inputElement, (_, args) => { + if (args.NewSource is not HwndSource hwndSource) + return; + IntPtr hwnd = hwndSource.Handle; + if (hwnd == IntPtr.Zero) + return; + + const uint DWMWA_WINDOW_CORNER_PREFERENCE = 33; + var attrValue = (RoundedCornerType)e.NewValue; + DwmSetWindowAttribute(hwnd, DWMWA_WINDOW_CORNER_PREFERENCE, ref attrValue, sizeof(uint)); + }); + } + + [DllImport("dwmapi", CharSet = CharSet.Unicode, PreserveSig = false)] + static extern void DwmSetWindowAttribute(IntPtr hwnd, uint attribute, ref RoundedCornerType pvAttribute, uint cbAttribute); + } +} diff --git a/dnSpy/dnSpy/Themes/wpf.styles.templates.xaml b/dnSpy/dnSpy/Themes/wpf.styles.templates.xaml index 51fd23d3ee..bed4d2a1ab 100644 --- a/dnSpy/dnSpy/Themes/wpf.styles.templates.xaml +++ b/dnSpy/dnSpy/Themes/wpf.styles.templates.xaml @@ -5338,6 +5338,7 @@ +