Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[WPF] 在 Windows 11 中处理 WindowChrome 的圆角

[WPF] 在 Windows 11 中处理 WindowChrome 的圆角

作者头像
dino.c
发布于 2021-11-02 08:48:27
发布于 2021-11-02 08:48:27
3.1K00
代码可运行
举报
文章被收录于专栏:dino.c的专栏dino.c的专栏
运行总次数:0
代码可运行

1. Windows 11 的圆角

在直角统治了微软的 UI 设计多年以后,微软突然把直角骂了一顿,说还是圆角好看,于是 Windows 11 随处都可看到圆角设计。Windows 11 使用 3 个级别的圆角,具体取决于要应用圆角的 UI 组件及该组件相对于相邻元素的排列方式。

圆角半径

使用情况

8px

窗体、Flyout 、弹出菜单等 。另外,当窗体最大化或使用对齐布局时不应用圆角。

4px

页面内的元素,如按钮或列表等。

0px

与其它直边相交的直边不使用圆角。

也就是说在 Windows 11 上窗体需要应用半径为 8px 的圆角。

2. 处理 WindowChrome 的圆角

对于 WPF,如果使用原生 Window 的话不需要额外处理圆角,如果使用了 WindowChrome 自定义窗体样式的话呢?

结论是,如果自定义的 Window 使用了 1 像素的窄边框或无边框的样式,那就可能不需要额外处理。

下面这两张图是同一个自定义的 Window 分别在 Windows 11 和 10 上的样子:

可以看到这是个模仿 Windows 10 的 Window 样式,边框只有 1 像素。在 Windows 11 里 WindowChrome 会自动裁剪最外层那 1 像素边框和圆角的其它部分,然后补上一条灰色的边框。这做法简单粗暴但有效。被裁剪过后自定义的 Window 成了一个无边框圆角窗口,看着还挺时髦的。

但这个简单裁剪也可能遇到问题,如果 Window 里的内容正好有个直角的元素,而且这个直角还靠着圆角,就可能被裁剪掉;或者自定义的 Window 使用了无边框的样式,那么这个贴边的边框就会被裁剪掉一像素:

所以 Window 可能不需要额外处理,但内容可能需要,这取决于以前的设计。

还有一种情况,如果这个 Window 的边框大于一个像素(像 Windows 8 那样的粗边框),那就需要修改 Window 样式了:

3. 我就是喜欢直的,不想要圆角,怎么办

上图是 Aero2 的主题样式,这是 Windows 8 以后 WPF 程序的默认主题,再之后微软就没有更新过 WPF 的主题。即使在 Windows 11 上,WPF 的主题也没有获得更新。所以,假使现有的 WPF 程序使用了默认主题,或者自定义的主题按照微软一向的审美全使用了直角元素,那到了 Windows 11 上就会显得格格不入。

微软还是很贴心的,如果我们不想更改样式,可以使用 DwmSetWindowAttribute 和 DWM_WINDOW_CORNER_PREFERENCE 控制 Window 的圆角。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Runtime.InteropServices;
using System.Windows.Interop;

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();

        IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
        var attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
        var preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
        DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));

        // ...
        // Perform any other work necessary
        // ...
    }


    // The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
    public enum DWMWINDOWATTRIBUTE
    {
        DWMWA_WINDOW_CORNER_PREFERENCE = 33
    }

    // The DWM_WINDOW_CORNER_PREFERENCE enum for DwmSetWindowAttribute's third parameter, which tells the function
    // what value of the enum to set.
    public enum DWM_WINDOW_CORNER_PREFERENCE
    {
        DWMWCP_DEFAULT = 0,
        DWMWCP_DONOTROUND = 1,
        DWMWCP_ROUND = 2,
        DWMWCP_ROUNDSMALL = 3
    }

    // Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
    [DllImport("dwmapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern long DwmSetWindowAttribute(IntPtr hwnd,
                                                     DWMWINDOWATTRIBUTE attribute,
                                                     ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
                                                     uint cbAttribute);

    // ...
    // Various other definitions
    // ...
}

其中 DWM_WINDOW_CORNER_PREFERENCE 枚举值的含义如下:

枚举值

说明

DWMWCP_DEFAULT

让系统决定是否对窗口采用圆角设置。

DWMWCP_DONOTROUND

绝不对窗口采用圆角设置。

DWMWCP_ROUND

适当时采用圆角设置。

DWMWCP_ROUNDSMALL

适当时可采用半径较小的圆角设置。

在 Windows 11 上,使用了上面 4 钟枚举值的窗口效果如下:

4. 最后

关于使用 WindowChrome 自定义窗体的内容,可以参考这几篇文章:

另外,关于圆角我要抱怨一下:

在 Windows 11 中,我们对窗口边框进行了圆角处理。 我们的用户研究团队发现,圆润的几何图形在心理上提供一种安全感,并且使应用的 UI 更易于扫描。 这使用户更少感觉威慑,也使应用更具吸引力。 圆角处理的量也是精心选择的。 我们公司对此进行了研究,努力在专业性、柔和感和吸引度之间取得平衡。

微软的文档这样声称,我是一个字都不信的,难道这么多年来区区 Windows 的直角就让我感觉到威慑和没有安全感了?微软还有比 UWP 更能让我没有安全感的东西?我倒想看看几年后又流行直角时微软要怎么解释。

5. 参考

在 Windows 11 的桌面应用中应用圆角

在 Windows 11 上,为增强应用功能而可以执行的最常见的 11 种操作

Windows 11 中的几何图形

6. 源码

我做了个小 Demo 用户看看这篇文章提到的不同边框和 DWM_WINDOW_CORNER_PREFERENCE 设定下的效果,源码可以从这里获取:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[WPF]使用WindowChrome自定义Window Style
做了WPF开发多年,一直未曾自己实现一个自定义Window Style,无论是《WPF编程宝典》或是各种博客都建议使用WindowStyle="None" 和 AllowsTransparency="True",于是想当然以为这样就可以了。最近来了兴致想自己实现一个,才知道WindowStyle="None" 的方式根本不好用,原因有几点:
dino.c
2019/01/18
2.3K0
[WPF]使用WindowChrome自定义Window Style
WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)
发布于 2018-07-12 07:57 更新于 2018-09-05 05:46
walterlv
2018/09/18
6.8K0
WPF 使用 WindowChrome,在自定义窗口标题栏的同时最大程度保留原生窗口样式(类似 UWP/Chrome)
使用 SetWindowCompositionAttribute 来控制程序的窗口边框和背景(可以做 Acrylic 亚克力效果、模糊效果、主题色效果等)
Windows 系统中有一个没什么文档的 API,SetWindowCompositionAttribute,可以允许应用的开发者将自己窗口中的内容渲染与窗口进行组合。这可以实现很多系统中预设的窗口特效,比如 Windows 7 的毛玻璃特效,Windows 8/10 的前景色特效,Windows 10 的模糊特效,以及 Windows 10 1709 的亚克力(Acrylic)特效。而且这些组合都发生在 dwm 进程中,不会额外占用应用程序的渲染性能。
walterlv
2023/10/22
1.8K0
使用 SetWindowCompositionAttribute 来控制程序的窗口边框和背景(可以做 Acrylic 亚克力效果、模糊效果、主题色效果等)
[WPF自定义控件库]使用WindowChrome自定义RibbonWindow
自定义Window有可能是设计或功能上的要求,可以是非必要的,而自定义RibbonWindow则不一样:
dino.c
2019/06/16
1.2K0
[WPF自定义控件库]使用WindowChrome的问题
上一篇文章介绍了使用WindowChrome自定义Window,实际使用下来总有各种各样的问题,这些问题大部分都不影响使用,可能正是因为不影响使用所以一直没得到修复(也有可能别人根本不觉得这些是问题)。
dino.c
2019/06/16
1.4K0
WPF 渲染原理
在 WPF 最主要的就是渲染,因为 WPF 是一个界面框架。想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的。本文告诉大家 WPF 从开发者告诉如何画图像到在屏幕显示的过程。本文是从一个很高的地方来看渲染的过程,在本文之后会添加很多博客来告诉大家渲染的细节。
林德熙
2018/09/19
3K0
WPF 渲染原理
【炫丽】从0开始做一个WPF+Blazor对话小程序
注 要使WPF支持Blazor,.NET版本必须是 6.0 或更高版本,本文所有示例使用的.NET 7.0,版本要求见链接,截图看如下文字:
沙漠尽头的狼
2022/11/08
8.3K0
很棒的WPF开源控件库Newbeecoder.UI
Newbeecoder.UI是一个强大的WPF基于MVVM框架和控件库实用程序。它支持窗口边框阴影,窗口圆角,包含许多优雅的控件。它让开发人员更高效、更快地创建漂亮的WPF构建应用程序。它支持从4.0到4.8的.NET框架,还能在X86、X64上运行。
用户7152477
2022/01/25
2.6K0
aardio中使用HTMLayout构建页面
HTMLayout的功能特别强大,它相当于使用了HTML和CSS,但是干掉了JS(JS使用aardio语法实现),
码客说
2022/09/07
1.2K0
Windows 对全屏应用的优化
全屏应用对应的是窗口模式应用,全屏应用指的是整个屏幕都是被咱一个应用独占了,屏幕上没有显示其他的应用,此时的应用就叫全屏应用。如希沃白板这个程序。本文主要告诉大家从微软官方的文档以及考古了解到的 Windows 对全屏应用的优化,以及是如何进行的优化,方便小伙伴在撕的时候可以找到根据
林德熙
2020/05/09
2K0
UWP 和 WPF 对比
本文告诉大家 UWP 和 WPF 的不同。 如果在遇到技术选择或者想和小伙伴吹的时候可以让他以为自己很厉害,那么请继续看。
林德熙
2018/09/18
14.8K2
EasyX图形库学习(一)
EasyX 是针对 C++ 的图形库,可以帮助 C/C++ 初学者快速上手图形和游戏编程。
走在努力路上的自己
2024/02/03
6460
EasyX图形库学习(一)
WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
在 WPF 中,如果想做一个背景透明的异形窗口,基本上都要设置 WindowStyle="None"、AllowsTransparency="True" 这两个属性。如果不想自定义窗口样式,还需要设置 Background="Transparent"。这样的设置会让窗口变成 Layered Window,WPF 在这种类型窗口上的渲染性能是非常糟糕的。
walterlv
2023/10/22
1.9K0
WPF 制作高性能的透明背景异形窗口(使用 WindowChrome 而不要使用 AllowsTransparency=True)
[WPF] 实现 WPF 的 Inner Shadow
在 WPF 中,我们通常用 DropShadow 做阴影效果,但都是做外阴影。内阴影(Inner Shadow)的话其实也不是不可以,就是有些曲折。这篇文章介绍几种做内引用的做法。
dino.c
2021/12/28
1K0
[WPF] 实现 WPF 的 Inner Shadow
关于WPF空域的问题
1.Microsoft.DwayneNeed 怎么说呢 ,这个库我个人没觉得有多好用,因为视频小窗口特别多,用这个巨卡无比
tangmanger
2021/09/02
1.6K0
关于WPF空域的问题
WPF 应用完全模拟 UWP 的标题栏按钮
发布于 2018-08-04 09:35 更新于 2018-08-05 02:21
walterlv
2018/09/18
2.3K0
WPF 应用完全模拟 UWP 的标题栏按钮
WPF MVVM框架搭建Newbeecoder.UI控件库—Window窗口
在WPF开发中经常用到Window和Page两种界面,标准窗体分两个部分:非客户区和客户区。
用户7152477
2022/01/24
8480
Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32)
本文将介绍 Windows 系统中高 DPI 开发的基础知识。由于涉及到坐标转换,这种转换经常发生在计算的不知不觉中;所以无论你使用哪种 Windows 下的 UI 框架进行开发,你都需要了解这些内容,以免不断踩坑。
walterlv
2023/10/22
1K0
Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32)
Qt项目DeskGirl开发
不能播放gif,太大了,给个静态图片吧,实际上桌面壁纸是动态的,人物也是动态的,可自定义桌面壁纸,有默认的数字时钟壁纸
DeROy
2020/07/28
9880
Qt项目DeskGirl开发
WPF 稳定的全屏化窗口方法
本文来告诉大家在 WPF 中,设置窗口全屏化的一个稳定的设置方法。在设置窗口全屏的时候,经常遇到的问题就是应用程序虽然设置最大化加无边框,但是此方式经常会有任务栏冒出来,或者说窗口没有贴屏幕的边。本文的方法是基于 Win32 的,由 lsj 提供的方法,当前已在 500 多万台设备上稳定运行超过半年时间,只有很少的电脑才偶尔出现任务栏不消失的情况
林德熙
2021/08/13
5K0
推荐阅读
相关推荐
[WPF]使用WindowChrome自定义Window Style
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档