C++/WinRT 开发入门

说明

C++/WinRT 最初是用来开发 UWP 应用程序的。WinUI3 继承了 UWP 大部分API,重新设计了 UI 类型,C++/WinRT 也可用于 WinUI3 开发。
使用 C++ 的优点:

  1. 方便使用C++标准库。
  2. 方便使用大量的第三方C++库(通过vcpkg 包管理器)。
  3. 方便直接使用 Windows API (也就是 win32 C函数)。
  4. 更好的性能。
  5. 语言有更大的自由度,便于掌握每一个细节。

也有这些缺点:

  1. 上手难度可能会大一点。
  2. 预编译头文件 pch.pch 大小在 955MB 左右,整个项目大小在 1GB 以上。
    在这里插入图片描述
  3. 自定义运行时类型,需要通过 idl 文件(使用的 MIDL 3.0 语言并不难,十几分钟就能掌握)。
  4. 文件比较繁琐,一个 xaml 页面会有四个文件(.xaml, .h, .cpp, .idl)。通过将项目的所有 idl 文件集中到一个文件中,可以减少到三个文件。

运行时类型,投影类型

当新建一个 C++/WinRT WinUI3 APP项目时候,假设名称为App1,那么将会看到在三个命名空间中都会出现 MainWindow 类型:

  1. winrt::App1::MainWindow (运行时类型)。
  2. winrt::App1::implementation::MainWindow (投影类型)。
  3. winrt::App1::factory_implementation::MainWindow (这个类型一般是空白的,可以不用特别在意)。

这个运行时类型,是通过 idl 文件定义的,这描述了其中公开的成员(属性,函数,事件),但并不能在 idl 文件中实现这些成员。如果需要实现,winrt 是通过C++ 中 implementation:: 下同名的投影类型实现的。
当我们调用一个运行时类型的方法(比如:void Hello()),会被映射到 implementation:: 下同名类型的 void Hello() 。如果编译时在投影类型中找不到 idl 文件中定义的函数,就会报错,这也是常见的编译错误。

IDL 文件

参考文档
IDL 文件可以定义以下类型:

  1. 委托 (关键字 delegate)
    • 类似于函数指针,具体用法参考 C# 委托 。
  2. 结构 (关键字 struct)
    • 类中的字段是属性,会被当做函数,结构中的字段是公开的数据成员。
    • 结构定义在idl 好处是可以在 idl文件和c++文件中都能使用。
  3. 枚举(关键字 enum)
    • 枚举定义在 idl 的好处是可以在 idl 文件和c++文件中都能使用。
  4. 接口 (关键字 interface)
    • 约定了应该实现的属性,方法,事件。
  5. 运行时类型(关键字 runtimeclass)

常见的问题解决方法

  1. FileOPenPicker, FileSavePicker, FolderPicker 在C#中并不需要使用窗口句柄初始化,在 C++/WinRT 中需要用窗口句柄初始化。
#include <microsoft.ui.xaml.window.h>
#include <Shobjidl.h>

FolderPicker picker{}; 
picker.FileTypeFilter().Append(L"*"); 

// 初始化 picker 
auto initializeWithWindow {picker.as<::IInitializeWithWindow>()}; 
initializeWidthWindow->Initialize(hWnd); 

if(StorageFolder folder = co_await folderPicker.PickSingleFolerAsync())
{ ... }
  1. 现在 WinUi3 应用程序可以不用打包,编译后点击 .exe 文件就能运行。需要在 *.vcxproj 文件中进行以下修改:
  <PropertyGroup Label="Globals">
	
	<!-- 这行是已经存在的,需要将 true 修改为 false.  -->
    <AppxPackage>false</AppxPackage>

	<!-- 这行是新增的。 -->
    <WindowsPackageType>None</WindowsPackageType>
  </PropertyGroup>
  1. 在 idl 文件中,并不能直接使用 int, float, double, 之类的数据类型,需要使用 WinRt 类型名称替代,可以参考以下表格:
    在这里插入图片描述
  2. 如何在 C++/WinRt 中实现接口 INotifyPropertyChanged?
    第一步:在 idl 文件中,让运行时类型继承 Microsoft.UI.Xaml.Data.INotifyPropertyChanged 接口。
    第二步: 在 implementation:: 下的投影类型的 .h 文件中,新增以下内容:
public:
winrt::event_token PropertyChanged(winrt::Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
	return m_propertyChanged.add(handler); 
}
void PropertyChanged(winrt::event_token const& token) noexcept
{
	m_propertyChanged.remove(token); 
}

private:
event<Microsoft::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged {};

如果属性发生改变,需要触发事件可以这样做:

m_propertyChanged(*this, PropertyChangedEventArgs(propertyName));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DENG-TAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值