WinForm 使用 Win32 API 实现的无边框窗口
前言
时光荏苒,转眼已近是2025年了。不知不觉两年多没有研究代码了,在这期间 .NET 10 都快 RC 了,前几天刷手机看到张队公众号里有关于 .NET 9.0 AOT 发布的内容,所以写了这些代码来测试一下 AOT 编译的效果,并评估未来是否开发支持 AOT 编译的 NanUI 新版本。
关于 NanUI 项目,如果你还不了解,可以通过这个链接了解。
项目介绍
这个项目参考了老外的 C++ 代码,我用 C# 代码基于 WinForm 进行开发实现了一个简单的无边框窗口。其实在 NanUI 项目了已经有现成的无边框窗口实现,但那是基于 Form 类实现的。作为 Cef 浏览器的承载窗口其实只需要简单的窗体功能,Form 类提供的东西太多太杂反而在不同的 .NET 版本中还存在各种奇奇怪怪的问题。
所以我计划在未来版本的 NanUI 项目中,承载窗体将直接使用了 Win32 API 来创建,这样可以更好的统一窗体的行为。
本来这个项目可以使用纯 Win32 API 来实现,为什么我还是基于 WinForm 项目来编写呢?因为我懒得处理消息循环、DPI缩放等等问题, WinForm 已经帮我们处理好了。
目前代码已经推至 Gitee 仓库,有兴趣的朋友可以自行拉去研究。
第三方库
- Vanara - MIT License
使用说明
不出意外的话,直接打开项目就可以运行了。运行后将打开一个无边框的窗体,你可以通过以下快捷键进行操作:
- F1 : 在普通窗体和无边框窗体之间进行实时切换
- F2 : 在无边框窗体模式切换 DWM 的窗体阴影效果(Win7/Win10/Win11)
- F3 : 在无边框窗体模式切换拖动窗体移动功能
- F4 : 切换窗体的拖动改变大小功能
关于 AOT 编译
当前代码已经支持 .NET 9.0 AOT 编译,并且已经在 Windows 10 x64 系统和 Windows 11 上测试通过。如果你需要在其他平台上运行,请自行测试。
我在代码中尝试使用 WS_EX_NOREDIRECTIONBITMAP 来创建无重定向表面的窗口,并用 DwmSetWindowAttribute 方法设置 DWM_SYSTEMBACKDROP_TYPE 属性来启用 Windows 11 系统下面的 Mica 窗体背景特效。但可能是 Vanara 库的问题,一旦使用了 DwmSetWindowAttribute 方法,那么 AOT 编译后的程序运行就会崩溃。这个问题我还没有找到解决方案,我已经到 Vanara 的项目主页提交了 Issue,目前还没有得到该项目作者的回复。
由于 AOT 我并没有太深入的研究,所以如果有朋友知道如何解决欢迎交流。