首页 > 系统相关 >windows C++-使用 C++/WinRT 创作 API(一)

windows C++-使用 C++/WinRT 创作 API(一)

时间:2024-08-05 23:52:55浏览次数:14  
标签:windows C++ MyRuntimeClass API Windows winrt 时类 WinRT

这个系列中的 "投影” 不太好有准确的翻译,它的原文 是"projection",最开始我觉得可能翻译为 实现,但C++ 本身也有"实现(implementation )",这两个不同的词翻译为一个总觉得怪怪的。

本文展示了如何直接或间接使用 winrt::implements 基本结构来拓展创作 C++/WinRT API 。 在此上下文中,“创作”的同义词有“生成”或“实现” 。 介绍以下在 C++/WinRT 类型上实现 API 的情形(按此顺序)。

下面涉及 Windows 运行时组件,但其中的相关内容仅在 C++/WinRT 上下文中适用。

  • 你不是在创作一个 Windows 运行时类(运行时类);你只是想要实现一个或多个 Windows 运行时接口以便在应用内进行本地使用 。 例如, 你直接从 winrt::implements 派生并实现相关函数 ;
  • 你正在创作一个运行时类 。 你可能正在创作一个要从某个应用中使用的组件。 或者,你可能正在创作一个要从 XAML 用户接口 (UI) 使用的类型,在此情况下,你在同一个编译单元内实现和使用一个运行时类。 在这些情况下,你使用工具为你生成派生自 winrt::implements 的类 ;

在这两种情况下,实现 C++/WinRT API 的类型被称作“实现类型” 。请务必区分实现类型与投影类型的概念。 投影类型将在通过 C++/WinRT 使用 API 中进行介绍。

非创作运行时类

最简单的方案是,你的类型在实现 Windows 运行时接口,并且你将在同一个应用中使用此类型。 在这种情况下,你的类型不需要是运行时类;只是一个普通的 C++ 类。 例如,你可能会基于 CoreApplication 编写一个应用 。

如果你的类型被 XAML UI 引用,那么它确实必须是运行时类,即使它与 XAML 在同一个项目中,也不例外。 在这种情况下,请参阅若要创作要在 XAML UI 中引用的运行时类部分。

有关安装和使用 C++/WinRT Visual Studio 扩展 (VSIX) 和 NuGet 包。

在 Visual Studio 中,“Visual C++”>“Windows 通用”>核心应用 (C++/WinRT)”项目模板阐释了 CoreApplication 模式 。 该模式首先将 Windows::ApplicationModel::Core::IFrameworkViewSource 的实现传递给 CoreApplication::Run:

using namespace Windows::ApplicationModel::Core;
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    IFrameworkViewSource source = ...
    CoreApplication::Run(source);
}

// CoreApplication 使用接口来创建应用的第一个视图 。 
// 从概念上来说,IFrameworkViewSource 如下所示 。
struct IFrameworkViewSource : IInspectable
{
    IFrameworkView CreateView();
};

// 同样,从概念上来说,CoreApplication::Run 的实现执行此操作 。
void Run(IFrameworkViewSource viewSource) const
{
    IFrameworkView view = viewSource.CreateView();
    ...
}

// 因此,作为开发人员,应实现 IFrameworkViewSource 接口 。 
// C++/WinRT 具有基结构模板 winrt::implements,从而可以很容易实现一个或多个接口,
// 而不必求助于 COM 样式的编程 。 你可以从 implements 直接派生类型,然后实现接口的函数 。 
// 操作方法如下。
// App.cpp
...
struct App : implements<App, IFrameworkViewSource>
{
    IFrameworkView CreateView()
    {
        return ...
    }
}
...

// 这将由 IFrameworkViewSource 处理 。 下一步是返回实现 IFrameworkView 接口的对象 。 
// 你也可以选择在 App 上实现该接口 。 
// 下一个代码示例表示一个小型应用,该应用将至少会在桌面上运行一个窗口。
// App.cpp
...
struct App : implements<App, IFrameworkViewSource, IFrameworkView>
{
    IFrameworkView CreateView()
    {
        return *this;
    }

    void Initialize(CoreApplicationView const &) {}

    void Load(hstring const&) {}

    void Run()
    {
        CoreWindow window = CoreWindow::GetForCurrentThread();
        window.Activate();

        CoreDispatcher dispatcher = window.Dispatcher();
        dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
    }

    void SetWindow(CoreWindow const & window)
    {
        // Prepare app visuals here
    }

    void Uninitialize() {}
};
...

// 由于 App 类型是 IFrameworkViewSource,因此可以直接传递一个到 Run。
using namespace Windows::ApplicationModel::Core;
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
    CoreApplication::Run(winrt::make<App>());
}
在 winrt 组件中创作一个运行时类

如果你的类型打包在 Windows 运行时组件中,以便从另一个二进制文件(另一个二进制文件通常是应用程序)使用它,则你的类型必须是运行时类。 在 Microsoft 接口定义语言 (IDL) (.idl) 文件中声明运行时类(请参阅将运行时类重构到 Midl 文件 (.idl) 中)。

每个 IDL 文件生成一个 .winmd 文件,Visual Studio 会将所有这些合并为一个与根命名空间同名的文件。 最后生成的 .winmd 文件将是组件使用者将参考的文件。

下面是一个在 IDL 文件中声明运行时类的示例。

// MyRuntimeClass.idl
namespace MyProject
{
    runtimeclass MyRuntimeClass
    {
        // Declaring a constructor (or constructors) in the IDL causes the runtime class to be
        // activatable from outside the compilation unit.
        MyRuntimeClass();
        String Name;
    }
}

// 此 IDL 声明一个 Windows 运行时类。 
// 运行时类是一个可通过现代 COM 接口进行激活和使用(通常跨可执行文件)的类型。 
// 当你向项目和生成中添加 IDL 文件时,C++/WinRT 工具链(midl.exe 和 cppwinrt.exe)将
// 会为你生成一个实现类型。 

// 对于上面的示例 IDL,在名为 \MyProject\MyProject\Generated Files\sources\MyRuntimeClass.h // 和 MyRuntimeClass.cpp 的源代码文件中,实现类型是一个名为 
// winrt::MyProject::implementation::MyRuntimeClass 的 C++ 结构存根 。
// 该实现类型如下所示。
// MyRuntimeClass.h
...
namespace winrt::MyProject::implementation
{
    struct MyRuntimeClass : MyRuntimeClassT<MyRuntimeClass>
    {
        MyRuntimeClass() = default;

        winrt::hstring Name();
        void Name(winrt::hstring const& value);
    };
}

// winrt::MyProject::factory_implementation::MyRuntimeClass is here, too.

// 请注意所使用的 F 边界多态模式(MyRuntimeClass 使用自身作为其基类 
// MyRuntimeClassT 的模板参数)。 这也称为奇异递归模板模式 (CRTP)。 
// 如果你向上查看继承链,你就会发现 MyRuntimeClass_base 。

// 可以使用 Windows 实现库 (WIL)简化简单属性的实现。 操作步骤如下:

// MyRuntimeClass.h
...
namespace winrt::MyProject::implementation
{
    struct MyRuntimeClass : MyRuntimeClassT<MyRuntimeClass>
    {
        MyRuntimeClass() = default;

        wil::single_threaded_rw_property<winrt::hstring> Name;
    };
}

template <typename D, typename... I>
struct MyRuntimeClass_base : implements<D, MyProject::IMyRuntimeClass, I...>

因此,在此情况中,继承层次结构的根同样是 winrt::implements 基结构模板 。 

标签:windows,C++,MyRuntimeClass,API,Windows,winrt,时类,WinRT
From: https://blog.csdn.net/m0_72813396/article/details/140759520

相关文章

  • windows C++-使用 C++/WinRT 创作 API(二)
    可扩展应用程序标记语言(XAML)是一种声明性语言。具体来讲,XAML可初始化对象和设置对象的属性,使用一种可显示多个对象间分层关系的语言结构,还使用了一种支持类型扩展的支持类型约定。可以在声明性XAML标记中创建可见的UI元素。然后,可以为每个XAML文件关联单独的代码隐藏......
  • 权限,锁定解锁用户接口,发送短信接口,drf部分源码分析APIView源码,新的Request对象,序
    Ⅰ权限【一】ACL(AccessControlList,访问控制列表)#ACL(AccessControlList,访问控制列表) 将用户直接与与权限对接permission表iduser_id权限名11开直播21评论【二】RBAC(Role-BasedAccessControl,基......
  • C++ 拷贝构造函数语义与移动构造函数语义
    拷贝构造函数语义与移动构造函数语义一、拷贝构造函数语义1.编译器生成拷贝构造函数的条件2.自定义拷贝构造函数3.深拷贝与浅拷贝4.拷贝构造函数的使用场景5.拷贝赋值运算符6.规则五(RuleofFive)二、移动构造函数语义1.禁止生成移动构造函数2.生成移动构造函数......
  • [python]使用gunivorn部署fastapi服务
    前言Gunicorn是一种流行的WSGIHTTP服务器,常用于部署Django和Flask等PythonWeb框架程序。Gunicorn具有轻量级、高稳定性和高性能等特性,可以轻易提高PythonWSGIApp运行时的性能。基本原理Gunicorn采用了pre-fork模型,也就是一个工作进程和多个worker进程的工作模式。在这个模......
  • python项目学习 mediapipe手势识别 opencv可视化显示
    importcv2importmediapipeimportnumpydefget_angle(vector1,vector2):#角度计算angle=numpy.dot(vector1,vector2)/(numpy.sqrt(numpy.sum(vector1*vector1))*numpy.sqrt(numpy.sum(vector2*vector2)))#cos(angle)=向量的点乘/向量的模angle=nump......
  • Codeforces Round 963 (Div. 2) A - C 详细题解(思路加代码,C++,Python) -- 来自灰名
    比赛链接:Dashboard-CodeforcesRound963(Div.2)-Codeforces之后有实力了再试试后面的题目,现在要做那些题,起码要理解一个多小时题目A:链接:Problem-A-Codeforces题目大意理解:        极少数不考翻译能读懂的cf题目(bushi)每个测试用例第一行一个n,......
  • 【Playwright+Python】系列教程(七)使用Playwright进行API接口测试
    playwright也是可以做接口测试的,但个人觉得还是没有requests库强大,但和selenium相比的话,略胜一筹,毕竟支持API登录,也就是说可以不用交互直接调用接口操作了。怎么用既然是API的测试了,那肯定就别搞UI自动化那套,搞什么浏览器交互,那叫啥API测试,纯属扯淡。也不像有些博主更懒,直接贴......
  • C++_Const的相关知识点
    1.修饰函数参数,表示函数不会修改参数当const修饰函数参数时,表示函数内部不会修改该参数的值。这样做可以使代码更加安全,避免在函数内部无意中修改传入的参数值。尤其是引用作为参数时,如果确定不会修改引用,那么一定要使用const引用。voidfunc(constinta){......
  • C++ exe程序内存占用分析
    编译 $gitclonehttps://github.com/google/bloaty$cdbloaty$cmake-Bbuild-GNinja-S.$cmake--buildbuild$cmake--buildbuild--targetinstall命令bloaty.exe --list-sourcesrmembersthe.ofilesina.afilecompileunitssourcefile......
  • 【C++ 面试 - 基础题】每日 3 题(一)
    ✍个人博客:Pandaconda-CSDN博客......