C++/WinUI 3 技术笔记(一)
微软在 Windows 10 Version 1809 上正式发布了新的 UI 框架,命名为 WinUI 3。
这已经是微软发布的第不知道多少个 UI 框架了,但是微软宣称它将支持原生 C++ 和 Win32 应用。这引起了我的注意,因为微软已经很久没有为 Win32 提供新的技术了。
架构
按微软的说法,WinUI 3 是同时为 Win32 和 UWP 程序提供支持的,也就是说它应该允许独立运行在 Win32 框架上,不受 UWP 的权限管理限制。
对于 C++ 开发者,WinUI 3 借助 C++/WinRT 有完全的原生 C++ 支持,而不需要 C++/CX 或 C++/CLI 这样剑走偏锋的设计。这无疑对 GCC 或 Clang 上编译 WinUI 3 留下了可能。作为开发者,着实不希望微软带领技术走向分裂。
对于 UI 设计,WinUI 3 继承了 UWP 程序的 XAML 技术,为用户提供了 Fluent 风格的控件和交互体验。也就是说在核心的 UI 开发方式上,还是和 UWP 保持一致的,只是控件风格有所改变。但是 WinUI 3 不受 UWP 复杂的权限约束限制,可以说对 Win32 开发者十分友好了。
开发
开发环境
开发前按照微软文档配置安装环境。
Install tools for developing apps for Windows 10 and Windows 11
模板工程
开发环境搭建好后,通过工程模板
使用 Visual Studio 的 WinUI 3 创建模板创建工程。
WinUI 3 project templates in Visual Studio
以 C++/WinUI 3 为例,工程创建后,资源管理器中有不少项目,这里先关注两个重要的 xaml 项,其他文件的用途后续再研究。
App.xaml 描述了 Windows 应用的基本属性。App.xaml.h 和 App.xaml.cpp 实现了 WinRT 主应用类,这里封装了程序入口函数。
void App::OnLaunched(LaunchActivatedEventArgs const&)
{
window = make<MainWindow>();
window.Activate();
}
入口很简单,创建主窗口并激活。
MainWindow.xaml 描述了应用的主窗口界面,MainWindow.xaml.h 和 MainWindow.xaml.cpp 实现了主窗口类,这里封装了窗口事件回调。
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button x:Name="myButton" Click="myButton_Click">Click Me</Button>
</StackPanel>
主窗口描述了一个居中的堆叠布局,里面有一个按钮 myButton。
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
myButton().Content(box_value(L"Clicked"));
}
主窗口类也很简单,当按钮 myButton 点击时,替换其内容文本。
我们回头看 MainWindow 的定义。
struct MainWindow : MainWindowT<MainWindow>
{
MainWindow();
int32_t MyProperty();
void MyProperty(int32_t value);
void myButton_Click(
Windows::Foundation::IInspectable const& sender,
Microsoft::UI::Xaml::RoutedEventArgs const& args);
};
和传统的 Win32 UI 技术不同,MainWindow 类并没有消息处理函数,也无需处理消息循环,但是这个 myButton_Click 函数是如何和 MainWindow.xaml 中描述的 myButton 按钮绑定在一起呢?
追踪 myButton_Click 函数的调用,可以发现调用者在 MainWindow.xaml.g.h 文件中。这个文件正是 C++/WinRT 对 MainWindow.xaml 描述的对象生成的 C++ 代码。微软在符合 C++ 17 标准的前提下,通过使用大量新的语言特性,将 WinRT API 封装到头文件模板库中,供开发者使用。
编译运行模板工程。

测试了下这个窗口,无论是执行速度、字体渲染还是高 DPI 缩放都处理的很不错。不得不说,微软在技术实力和设计大框架上一直都让人很佩服(笑)。
添加页面
下面我们添加一个自己页面,在工程中插入一个新的 WinUI 3 空白页 RootPage.xaml。
界面和代码参考微软提供的 XAML 控件演示工程。
<NavigationView x:Name="RootNavigation">
<NavigationView.MenuItems>
<NavigationViewItem Icon="Play" Content="Menu Item1" Tag="SamplePage1" />
<NavigationViewItem Icon="Save" Content="Menu Item2" Tag="SamplePage2" />
<NavigationViewItem Icon="Refresh" Content="Menu Item3" Tag="SamplePage3" />
<NavigationViewItem Icon="Download" Content="Menu Item4" Tag="SamplePage4" />
</NavigationView.MenuItems>
<Frame x:Name="RootFrame"/>
</NavigationView>
在 Page 中描述一个侧边导航栏,和一个主页面框架,作为应用的基础结构。
void App::OnLaunched(LaunchActivatedEventArgs const&)
{
window = make<MainWindow>();
auto rootPage = make<RootPage>();
window.Content(rootPage);
window.Activate();
}
在入口函数中,把创建的页面对象塞进窗口中,一个简单的应用就搭好了。

布局、控件、页面路由和事件交互等话题在下一篇中讨论。
参考
作者:Lyin.CC
版权:本文采用「CC BY 4.0」知识共享许可协议进行许可。
地址:https://www.cnblogs.com/lyincc/p/cpp-winui-3-note-01.html
C++/WinUI 3 技术笔记(一)的更多相关文章
- WinUI 3学习笔记(3)—— ComboBox & DropDownButton & SplitButton
本篇想介绍相对小众但颇具使用价值的控件SplitButton,提到SplitButton难免会拿来与ComboBox进行比较,同时在WinUI 3的控件库中,还有一个默默无闻的DropDownButt ...
- 技术笔记:Indy的TIdSMTP改造,解决发送Html和主题截断问题
使用Indy来发邮件坑不少啊,只不过有比没有好吧,使用delphi6这种老工具没办法,只能使用了新一点的Indy版本9,公司限制... 1.邮件包含TIdText和TIdAttachment时会出现T ...
- PHP实现日志处理类库 - 【微信开发之微电商网站】技术笔记之二
继上篇文章[微信开发之微电商网站]技术笔记之一,昨日做了日志处理的功能. 对于现在的应用程序来说,日志的重要性是不言而喻的.很难想象没有任何日志记录功能的应用程序运行在生产环境中.日志所能提供的功能是 ...
- IPV6技术笔记(剖析IPv4toIPv6)
IPV6技术笔记 IPv6地址入门概念 什么是IPv6? IPv6,全称Internet Protocol version 6,即网际协议版本6,也叫互联网通信协议第六版.是互联网工程任务组(IETF ...
- 解决一个 MySQL 服务器进程 CPU 占用 100%解决一个 MySQL 服务器进程 CPU 占用 100%的技术笔记》[转]
转载地址:http://bbs.chinaunix.net/archiver/tid-1823500.html 解决一个 MySQL 服务器进程 CPU 占用 100%解决一个 MySQL 服务器进程 ...
- 开源爆款,阿里P7Android技术笔记,理论与实战齐飞,限时开放下载!
自我介绍 2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在. 被人面试过,也面试过很多人.深知大多数初中级Android工程师,想要 ...
- 技术笔记:Delphi多线程应用读写锁
在多线程应用中锁是一个很简单又很复杂的技术,之所以要用到锁是因为在多进程/线程环境下,一段代码可能会被同时访问到,如果这段代码涉及到了共享资源(数据)就需要保证数据的正确性.也就是所谓的线程安全.之前 ...
- Android硬盘缓存技术DiskLruCache技术笔记
防止多图OOM的核心解决思路就是使用LruCache技术,但LruCache只是管理了内存中图片的存储与释放,如果图片从内存中被移除的话,那么又需要从网络上重新加载一次,这显然非常耗时.因此Googl ...
- ebay的api的开发技术笔记
使用eBay API基本步骤介绍 要开始使用eBay API,需要如下基本步骤: 1. 注册开发帐号: https://developer.ebay.com/join/Default.aspx ...
随机推荐
- 家用路由器也能充当Web服务器?路由器插件开发心得
起因 最近刚刚结束考研,开始有时间写文章了.在复习的时候中,经常忍不住折腾各种东西,于是有一天看中了我手上的华为路由器.什么?华为路由器,你可能有这样的疑问,华为路由器不是自研的芯片吗,就像我手上这台 ...
- TSS任务状态段
TSS (任务状态段)的作用及结构 1.什么是TSS TSS全称Task State Segment ,是操作系统在进行进程切换时保存进程现场信息的段 2.TSS什么时候用,有什么用 TSS在任务 ...
- <学习opencv>图像变换
拉伸.收缩.扭曲和旋转 统一调整大小 我们经常会遇到一些我们希望转换为其他尺寸的图像. 我们可能想要扩大或缩小图像; 这两项任务都是由同一个功能完成的. cv::resize() 该cv::resiz ...
- [学习笔记] Oracle集合运算、内连接、外连接、伪列
集合运算 INTERSECT(交集),返回两个查询共有的记录. UNION ALL(并集重复),返回各个查询的所有记录,包括重复记录. UNION(并集不重复),返回各个查询的所有记录,不包括重复记录 ...
- .NET C#教程初级篇 1-1 基本数据类型及其存储方式
.NET C# 教程初级篇 1-1 基本数据类型及其存储方式 全文目录 (博客园).NET Core Guide (Github).NET Core Guide 本节内容是对于C#基础类型的存储方式以 ...
- android-tools下的uiautomatorviewer截图,提示“Unexpected error while obtaining UI hierarchy”
使用原来工具下的uiautomatorviewer对android 5.1.0的手机,进行截图,是正常的,切换到android10截图,就报错"Unexpected error while ...
- python 面向对象:类方法&静态方法
一.类方法 1.1 概念和语法说明 类方法就是针对类对象定义的方法.在类方法内部可以直接访问类属性或者调用其他的类方法 语法如下: @classmethod def 类方法名(cls): pass 说 ...
- kubeadm 安装Kubernetes 1.16.3 (CentOS7+IPVS+Calico)
目录 · . 一.更新系统内核(全部节点) · . 二.基础环境设置(全部节点) · . 1.修改 Host · . 2.修改 Hostname · . 3.主机时间同步 · . 4.关闭 ...
- Ant <Delete> 如何只删掉文件夹下所有文件和文件夹
用 fileset 来过滤要删掉的目录和文件 <project name="ant-project" default="example"> < ...
- Java基础复习到此结束,统一把源码放到GitHub仓库了,响应开源精神
这是地址 https://github.com/cen-xi/java-baisc-