惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Webroot Blog
Webroot Blog
U
Unit 42
A
About on SuperTechFans
宝玉的分享
宝玉的分享
月光博客
月光博客
C
CERT Recently Published Vulnerability Notes
P
Privacy International News Feed
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
P
Privacy & Cybersecurity Law Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
S
Securelist
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Spread Privacy
Spread Privacy
L
Lohrmann on Cybersecurity
Apple Machine Learning Research
Apple Machine Learning Research
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
B
Blog
I
Intezer
Last Week in AI
Last Week in AI
T
Threat Research - Cisco Blogs
V
V2EX
L
LangChain Blog
AI
AI
G
GRAHAM CLULEY
T
Tor Project blog
人人都是产品经理
人人都是产品经理
D
Docker
WordPress大学
WordPress大学
Google DeepMind News
Google DeepMind News
I
InfoQ
Y
Y Combinator Blog
C
Comments on: Blog
GbyAI
GbyAI
www.infosecurity-magazine.com
www.infosecurity-magazine.com
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tailwind CSS Blog
aimingoo的专栏
aimingoo的专栏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
N
News and Events Feed by Topic
MyScale Blog
MyScale Blog
H
Help Net Security
Vercel News
Vercel News
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
爱范儿
爱范儿

博客园 - zhaotianff

一文带你搞懂医疗器械设计开发全生命周期 Windows如何清除本机记录的git用户名和密码 HL7协议详解 医疗行业 GDT 数据格式详解 一文带你搞懂C# 异步编程(async/await)底层原理 如何在C#中使用Chromium headless(无头模式)浏览器 不同.NET版本中的WPF新增功能 如何在WPF中使用 Fluent 主题 C#如何Hook托管函数 WinDbg 用户层调试进阶教程 Windows编程的一些基础理论 推荐一款优秀的Windows经典文件管理器项目-WinFile Windows如何阻止应用程序联网 如何在WPF中捕获窗口外的事件 如何查看Windows进程的启动来源 Visual Studio 2026新解决方案格式slnx详解 我的微软MVP申请通过了 WPF MVVM实战系列教程(八、Prism DialogService, 对话框服务) WPF MVVM实战系列教程(七、Prism模块化) WPF 性能优化实战指南 WPF MVVM实战系列教程(六、Prism区域导航) WPF MVVM实战系列教程(五、Prism中的MVVM) WPF MVVM实战系列教程(四、Prism中的依赖注入) 微软 IDE 新纪元:Visual Studio 2026 初体验 Windows 7无法安装VMWare Tools的解决办法 WPF MVVM实战系列教程(三、创建Bootstrapper/启动器) WPF MVVM实战系列教程(二、使用Visual Studio 创建Prism项目) WPF MVVM实战系列教程(一、Prism框架介绍)
Windows平台下的各种原生UI框架介绍
zhaotianff · 2026-04-28 · via 博客园 - zhaotianff

WPF

WPF(Windows Presentation Foundation)是用于Windows的现代图形显示系统,使用WPF可以创建适用于Windows平台的具有非凡视觉效果的桌面应用程序。

WPF的底层图形技术使用了DirectX,而不是GDI/GDI+。这就意味的WPF在渲染图形时,会尽可能将处理工作交给GPU去处理,渲染的速度会更快,效果也会更好。WPF设计的出发点就是充分利用现代图形硬件。

WPF具有分辨率无关性,WPF会根据系统DPI进行缩放。(如何在Windows10系统中修改DPI设置,可参考以下链接https://support.corel.com/hc/en-us/articles/115001485408-Display-Options-How-to-change-DPI-Scaling-Level-for-displays-in-Windows-10-)

WPF目前已经开源,项目地址

https://github.com/dotnet/wpf 

WPF未来发展路线

https://github.com/dotnet/wpf/blob/master/roadmap.md

WPF的功能和特性:

1、使用XAML标记语言来构建界面

2、前后端分离,使用C#语言作为后台逻辑代码语言。

3、控件

 WPF内置控件

4、输入和命令系统

5、布局

6、数据绑定

7、图形(包括二维和三维图形)

8、动画

9、图像、视频和音频支持

10、文字和排版

11、内容模型

12、触发器

13、控件模板

14、数据模板

15、样式

16、资源

17、自定义控件

WPF体系结构

体系结构说明:

PresentationFramework.dll

包含WPF顶层的类型。包括窗口、面板以及控件等。它还实现了高层编程抽象,如样式。平常我们使用的大部分类都来自这个程序集。

PresentationCore.dll

包含了基础类型,如UIElement类和Visual类,所有形状类和控件类都继承自这两个类。

WindowsBase.dll

包含了更多基本要素,如DispatcherObject和DependencyObject类,这两个类实现了依赖属性

milcore.dll

WPF渲染系统的核心,也是媒体集成层(Media Integration Layer)的基础。它将可视化元素转换为DirectX所需要的三角形和纹理。milcore.dll也是操作系统的一部分,DWM使用milcore.dll来渲染桌面。(不得不说,这一点很强)

WindowsCodecs.dll

提供图像处理支持的低级API(如处理、显示以及缩放常用图像格式)

DirectX

一套多媒体编程接口。WPF应用程序中的所有图形都由它进行渲染

User32

用于决定应用程序实际占用桌面的哪一部分(在Winform中,该库还用于渲染图像)

WPF界面效果演示

image

 WPFDevelopers UI库

官方文档:

https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/overview/

Windows Forms(Windows窗体开发, 简称Winforms)

Winforms是一个 UI 框架,用于创建适用于 Windows 的丰富桌面客户端应用。

Winforms支持广泛的应用开发功能,包括控件、图形、数据绑定和用户输入。

Visual Studio 自带Winforms视觉设计器,可轻松创建 Windows 窗体应用。

demo

 Winforms视觉设计器

Winforms目前已经开源,项目地址

https://github.com/dotnet/winforms 

在前面的文章中我介绍过如何使用Win32 API来创建窗口及处理消息

https://www.cnblogs.com/zhaotianff/p/11297319.html

Winforms本质上是调用了Win32 API来创建窗口及控件。底层使用的是GDI+技术。 事件处理基于Windows 消息循环。

可以看到Winforms在创建窗口/控件时调用的函数

 1 public virtual unsafe void CreateHandle(CreateParams cp)
 2     {
 3         lock (_lock)
 4         {
 5             CheckReleased();
 6             WindowClass windowClass = WindowClass.FindOrCreate(cp.ClassName, (WNDCLASS_STYLES)cp.ClassStyle);
 7             lock (s_createWindowSyncObject)
 8             {
 9                 if (!HWND.IsNull)
10                 {
11                     return;
12                 }
13  
14                 HWND createResult = HWND.Null;
15                 int lastWin32Error = 0;
16  
17                 NativeWindow? prevTargetWindow = windowClass._targetWindow;
18                 try
19                 {
20                     windowClass._targetWindow = this;
21  
22                     using (ScaleHelper.EnterDpiAwarenessScope(DpiAwarenessContext, DPI_HOSTING_BEHAVIOR.DPI_HOSTING_BEHAVIOR_MIXED))
23                     {
24                         HINSTANCE modHandle = PInvoke.GetModuleHandle((PCWSTR)null);
25                         try
26                         {
27 
28                             if (cp.Caption is not null && cp.Caption.Length > short.MaxValue)
29                             {
30                                 cp.Caption = cp.Caption[..short.MaxValue];
31                             }
32  
33                             //调用CreateWindowEx创建窗口及控件
34                             createResult = PInvoke.CreateWindowEx(
35                                 (WINDOW_EX_STYLE)cp.ExStyle,
36                                 windowClass._windowClassName,
37                                 cp.Caption,
38                                 (WINDOW_STYLE)cp.Style,
39                                 cp.X,
40                                 cp.Y,
41                                 cp.Width,
42                                 cp.Height,
43                                 (HWND)cp.Parent,
44                                 HMENU.Null,
45                                 modHandle,
46                                 cp.Param);
47  
48                             lastWin32Error = Marshal.GetLastWin32Error();
49                         }
50                         catch (NullReferenceException e)
51                         {
52                             throw new OutOfMemoryException(SR.ErrorCreatingHandle, e);
53                         }
54                     }
55                 }
56                 finally
57                 {
58                     windowClass._targetWindow = prevTargetWindow;
59                 }
60                 ........
61             }
62         }
63     }

Winforms提供的控件

1)基础控件

  • Label:显示静态文本
  • TextBox:单行 / 多行输入
  • Button:按钮(Click 事件)
  • CheckBox:复选框
  • RadioButton:单选按钮(分组互斥)
  • ComboBox:下拉列表
  • ListBox:列表框
  • PictureBox:显示图片
  • DateTimePicker:日期时间选择

2)容器控件(布局与分组)

  • Panel:无边框容器,用于分组 / 滚动
  • GroupBox:带标题边框分组
  • TabControl:多标签页
  • SplitContainer:可拖动分割面板
  • TableLayoutPanel:表格布局(类似 HTML 表格)
  • FlowLayoutPanel:流式布局(自动换行)

3)数据控件(数据库 / 集合显示)

  • DataGridView:表格显示数据(绑定 DataTable/List)
  • BindingSource:数据源中介(简化绑定、排序、过滤)
  • BindingNavigator:导航工具栏(增删改、导航)

4)菜单与工具栏

  • MenuStrip:主菜单
  • ToolStrip:工具栏
  • ContextMenuStrip:右键菜单

Windows Forms和WPF的对比

特性WinFormsWPF
渲染引擎 GDI+(像素) DirectX(矢量)
界面定义 代码 / 设计器 XAML(声明式)
数据绑定 简单绑定 强大 MVVM 绑定
样式定制 困难 灵活(模板 / 资源)
学习曲线 平缓 较陡
适用场景 企业管理系统、工具软件 现代 UI、多媒体、图形密集

Winforms也支持样式定制,但是是基于重绘机制,所以比较麻烦。

但是也有不少的开源控件库,以下是SunnyUI的界面演示效果

image

SunnyUI

Sunny UI

https://gitee.com/yhuse/SunnyUI

官方文档

https://learn.microsoft.com/zh-cn/dotnet/desktop/winforms/overview/

Win32

Win32桌面应用(也称为经典桌面应用)使用 C++ 直接访问 Windows 和硬件。

对于需要最高级别的性能、硬件级优化和 DirectX access的应用,这是最佳选择。

Win32桌面应用无需依赖于 .NET 和 WinRT 等托管运行时环境(对于适用于 Windows 10 的 UWP 应用)。

可以把它理解为这是Windows最原生,也是最接近底层的桌面应用开发技术,它使用的API都是操作系统直接提供的。

在过去游戏引擎不发达的阶段,很多游戏是Win32窗口的基础上直接使用DirectX API进行开发。

image

 SysInternals Suit中的 Process Monitor工具

C++/WinRT

在Win32桌面开发中,我们可以配置为使用 C++/WinRT。

C++/WinRT 是一种完全标准的现代 C++17 语言投影,可用于从 C++ Win32 桌面应用轻松使用 Windows 运行时 API(WinRT) API。

C++/WinRT 是作为基于头文件的库实现的。

在前面的文章中,我介绍过如何在WPF中使用Windows 运行时

https://www.cnblogs.com/zhaotianff/p/17320807.html

借助C++/WinRT,在Win32桌面开发中,也可以使用这些Windows运行时API.

一个最小的 Windows 桌面程序示例

使用C/C++

 1 #ifndef UNICODE
 2 #define UNICODE
 3 #endif 
 4 
 5 #include <windows.h>
 6 
 7 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 8 
 9 int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
10 {
11     // Register the window class.
12     const wchar_t CLASS_NAME[]  = L"Sample Window Class";
13     
14     WNDCLASS wc = { };
15 
16     wc.lpfnWndProc   = WindowProc;
17     wc.hInstance     = hInstance;
18     wc.lpszClassName = CLASS_NAME;
19 
20     RegisterClass(&wc);
21 
22     // Create the window.
23 
24     HWND hwnd = CreateWindowEx(
25         0,                              // Optional window styles.
26         CLASS_NAME,                     // Window class
27         L"Learn to Program Windows",    // Window text
28         WS_OVERLAPPEDWINDOW,            // Window style
29 
30         // Size and position
31         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
32 
33         NULL,       // Parent window    
34         NULL,       // Menu
35         hInstance,  // Instance handle
36         NULL        // Additional application data
37         );
38 
39     if (hwnd == NULL)
40     {
41         return 0;
42     }
43 
44     ShowWindow(hwnd, nCmdShow);
45 
46     // Run the message loop.
47 
48     MSG msg = { };
49     while (GetMessage(&msg, NULL, 0, 0) > 0)
50     {
51         TranslateMessage(&msg);
52         DispatchMessage(&msg);
53     }
54 
55     return 0;
56 }
57 
58 LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
59 {
60     switch (uMsg)
61     {
62     case WM_DESTROY:
63         PostQuitMessage(0);
64         return 0;
65 
66     case WM_PAINT:
67         {
68             PAINTSTRUCT ps;
69             HDC hdc = BeginPaint(hwnd, &ps);
70 
71             // All painting occurs here, between BeginPaint and EndPaint.
72 
73             FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
74 
75             EndPaint(hwnd, &ps);
76         }
77         return 0;
78 
79     }
80     return DefWindowProc(hwnd, uMsg, wParam, lParam);
81 }

运行效果

b2f54de4b5b90eae869abd0e6c56af76_window01

Win32桌面开发的一些衍生框架

ATL (Active Template Library)

官方文档地址:https://learn.microsoft.com/zh-cn/cpp/mfc/mfc-and-atl?view=msvc-170

活动模板库(ATL)是一个包装库,可简化 COM 开发,并用于创建 ActiveX 控件。

WTL (Windows Template Library)

项目地址:https://github.com/Win32-WTL/WTL

WTL是一组扩展了ATL的类,旨在支持应用程序或各种用户界面(UI)组件的更复杂用户界面,同时保持了ATL的一大优势——代码简洁且运行迅速。

WTL类被设计为基于ATL的应用程序、服务器、组件和控件实现丰富Win32用户界面的最佳且最简单方法。

MFC (Microsoft Foundation Classes)

官方文档地址:https://learn.microsoft.com/zh-cn/cpp/mfc/mfc-and-atl?view=msvc-170

Microsoft基础类(MFC)为 Win32 提供面向对象的 C++ 包装器,以便快速开发原生桌面应用程序。

MFC也提供了视觉设计器,可以方便的设计界面。

image

 MFC视觉设计器

Duilib

项目地址:https://github.com/duilib/duilib

Duilib是一个Windows下免费开源的DirectUI界面库,由于简约易扩展的设计以及稳定高效的实现被各大互联网公司普遍接受,广泛应用于包括IM、视频客户端、股票行情软件、导航软件、手机辅助软件、安全软件等多个行业的众多pc客户端软件。

它是国内流行的轻量 DirectUI 框架,底层基于 Win32,使用XML 布局,C++ 语言调用。

框架语言底层特点
纯 Win32 C/C++ 系统 API 原生、繁琐
MFC C++ Win32 老牌、重量级
WTL C++ Win32 + ATL 轻量、极速
Duilib C++ Win32 + GDI/DirectUI 精简自绘库

 Win32和衍生框架对比

UWP

Universal Windows Platform,通用Windows平台,它的前身是Windows RT(Windows Runtime,Windows运行时)。

在Windows 8/8.1时期,Windows推出了Windows RT,到Windows 10时,改名为UWP。

UWP核心价值是一次开发、多端运行、统一体验、安全沙盒,覆盖 PC、平板、Xbox、HoloLens 等全系列 Windows 设备。

UWP开发模型

Windows 10时期,系统的很多功能都切换到了UWP进行开发,例如系统设置界面、计算器等。

image

Windows设置-网络和Internet设置

image

 计算器

UWP应用提供的功能

  • 安全:UWP 应用声明其访问哪些设备资源和数据 用户必须对该访问授权。
  • 能够在运行Windows的所有设备上使用通用 API。
  • 可以使用设备的特定功能并让 UI 适应不同的设备屏幕尺寸、分辨率和 DPI。
  • 可以从运行Windows 10或Windows 11的所有设备(或仅您指定的那些设备)的Microsoft Store中获取。 Microsoft Store提供了多种方式在应用中赚钱。
  • 能够在不对计算机构成风险或引起“计算机腐烂”的情况下安装和卸载。
  • 引人入胜:使用与Windows时间线和 Cortana 的“选取离开位置”交互的动态磁贴、推送通知和用户活动来吸引用户。
  • C#、C++、Visual Basic 和 JavaScript 中的可编程。 对于 UI,请使用 WinUI、XAML、HTML 或 DirectX。

15年的时候我读过一本《Windows Runtime Via C#》的书籍,里面详细介绍了Windows Runtime(UWP的前身),当时我就被里面的各种新机制所吸引。

具体的内容我已经忘得差不多了,我印象比较深的就是它的挂起机制,应用退到后台几秒后进入(挂起),进程驻留内存但不占用 CPU,可快速恢复,传统的Win32应用是无法做到这一点的。

UWP带来了很多良好的使用体验

1、基于沙箱运行,安全可靠

2、低资源占用, 本地存储和内存占用都较低

3、图形体验较好

4、一次开发,Windows各种设备运行,包括电脑、平板、Xbox、HoloLens、Surface Hub、IoT 设备等。

但是UWP也有不少令人诟病的地方

1、强制商店分发

UWP应用无法像Win32应用那样,随下随用。Windows用户早就习惯了Win32应用的使用模式,突然要到商店下载,提升了软件使用门槛 

2、商店体验差

Microsoft Store的使用体验极差,经常打不开,下载速度也极慢。

3、强制沙盒运行

UWP强制应用在“沙盒”环境中运行,权限被严格限制,无法像传统的Win32应用那样自由地进行底层系统操作

4、开发较为繁琐

调试、部署、打包流程繁琐,不如 Win32 的 “编译即用” 简单。

主要还是战略定位问题,导致UWP没落了。

微软方面在2025年10月停止UWP版Microsoft 365应用功能更新。

连微软自己都放弃,基本可以说凉凉了。

但不得不说,当时WinRT刚出来的时候,真的帅得不行。

image

 Windows 8 Metro开始菜单

image

Windows Phone 8.1

UWP官方文档链接

https://learn.microsoft.com/zh-cn/windows/uwp/

WinUI3

UWP没落后,微软又推出了WinUI3。

WinUI 3 是Microsoft用于生成Windows桌面应用程序的现代本机用户界面框架。 它为 C# 和C++开发人员带来了 Fluent Design System、高性能呈现和基于 XAML 的强大编程模型。

WinUI 作为 Windows 应用 SDK 的一部分提供,可用于创建在 Windows 10 版本 1809(内部版本 17763)及更高版本(包括 Windows 11)上运行的现代、美观和响应式桌面体验。

严格意义上来说,UWP它是一个平台,它使用的是WinUI2 UI框架。

WinUI 3是解除了UWP平台限制的“下一代UI框架”。

这里我们可以看一下UWP和WinUI3的一个对比

对比项UWPWinUI 3
应用模型 沙盒(AppContainer),权限受限 传统 Win32 桌面进程,完全系统权限(可选沙盒运行)
API 访问 仅 UWP 受限 API,可调用用限的 Win32 可直接调用所有 Win32 + .NET API
部署方式 只能 MSIX/Store,强制商店审核 EXE 直接运行、MSIX、Store、传统安装包均可
性能与资源 由系统紧密管理,经过多年优化,内存控制更为精准 目前启动速度、内存占用和安装包大小略逊于UWP
生命周期管理 严格。进入后台会被立即暂停以节省资源(限制了后台任务)。 与Win32应用保持一致
界面开发语言

XAML

XAML
生态位与发展

功能完善。成熟平台,但正被逐步取代

目前官方推荐的未来Windows应用开发方向,

Windows11的大量应用都使用WinUI3开发

 UWP和WinUI3对比

在前面的文章中,我介绍过,如何创建一个WinUI3的应用程序

https://www.cnblogs.com/zhaotianff/p/16149790.html

c7578afe4f27c01a4f7e6b28c50ba0f8_Screenshot-light_raw=true

 WinUI3 Gallery

WinUI3和Windows 11深度集成,Windows shell 及其内置应用的某些部分是使用 WinUI 3生成的。 PowerToys 等开源项目也使用 WinUI 3生成。

ed4e625cf78b9529bfc7fcbc17ba303

 Windows 11设置界面

WinUI3官方文档链接

https://learn.microsoft.com/zh-cn/windows/apps/winui/winui3/

所有UI框架对比

功能WinUI3WPFWindows FormsUWPWin32
语言 C#、C++ C#、Visual Basic C#、Visual Basic C#、C++、Visual Basic C++、Rust
UI 语言 XAML XAML Code XAML Code
UI 设计器 (拖拽)
新式 UI ✅ (Fluent theme ✅ (WinUI 2
跨平台
沙盒 (AppContainer)
积极维护中 ⚠️ 仅限安全与漏洞修复