65.9K
CodeProject 正在变化。 阅读更多。
Home

C++/WinRT 运行时组件在 Win32 应用程序中 - 第三部分

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2022 年 1 月 14 日

CPOL

10分钟阅读

viewsIcon

9145

downloadIcon

246

如何创建一个“消耗” C++/WinRT 组件运行时的 Win32 C++ 应用程序

引言

注意:在同一个 Visual Studio 解决方案中,我们将创建一个 C++/WinRT 运行时组件项目,在其中实现运行时类,以及一个使用它们的 Win32 C++ 经典应用程序项目。对于 Win32 经典应用程序,我将使用基于同名的 C++ 框架的 Visual Studio 2019 的项目模板,用于 Win32:Win32Framework,其带有 Ribbon 的版本,我本人和我的团队经常将其用作 Win32 C++ 应用程序的起点,因为它简化并加快了工作。(项目模板和 Win32Framework 都是我的创作,并且仅在我 C++ 团队内部分发,但不能排除将来我可能会在此网站或 GitHub 上发布 Win32Framework 的一个版本)。

当然,Win32Framework 不是强制性要求,你可以自由使用最适合你的 C++ 项目类型,只要它基于C++ 标准 17

那么第一步就是在一个新的 Visual Studio 2019 C++ 项目中进行创建。

注意:在本教程中,你使用的是 Visual Studio 2019 版本 16.8.x。

我们为新项目选择一个具有代表性的名称,我选择了 `UWPWin32Demo`,并创建了同名的文件夹。

项目创建完成后,我们将看到框架的欢迎和许可页面,Readme 文件以及已打开 `CFrameWindow.h` 和 `CFrameWindow.cpp` 文件的选项卡。

注意:基于 Win32Framework Ribbon 框架的项目已准备好使用 C++ 17 标准语言进行编译。如果你的项目不是,请转到属性 -> 通用 -> C++ 语言标准,并确保选择版本 17 [ISO C++17 Standard (/std:c++17)]。

我们构建应用程序以验证一切是否正常,或者运行 Win32 应用程序的调试会话(请参阅上面的图片)。

如果你的 C++ Win32 入门应用程序使用 C++ 17 标准编译并且也正常,那么让我们进入第二步:将由我们的应用程序“消耗”的自定义运行时组件。

注意:要使运行时组件被其他应用程序“消耗”,该类必须是一个运行时类。如果我们想在本地应用程序中使用运行时组件,也就是说,仅在同一个项目中,一个普通的 C++ 类就足够了。

我们添加一个新项目,并选择模板:Windows Runtime Component C++/WinRT。本例中的 WinRT 组件将处理一个队列删除系统,因此我们为 UWP 项目选择了有代表性的名称:`TicketMachine`。

我们选择操作系统的最小和最大目标版本,然后确认。

如前所述(见第一部分) Visual Studio 向导除了提供编译和在运行时正确实例化组件所需的一切之外,还为我们创建了一个名为 `Class` 的运行时类以及 `Class.idl` 文件:更具体地说,我们找到三个文件

  1. Class.idl
  2. Class.h
  3. Class.cpp

`.idl` 文件定义了 C++/WinRT (Runtime Classes) 类。通过打开 `.idl` (Interface Definition Language) 文件,该文件将在项目编译期间被提供给 MICROSOFT Interface Definition Language (MIDL) 工具,你可以看到其 3.0 版本的新 IDL 语言语法。

对于不了解 COM (Component Object Model) 的人来说,请记住 `.idl` 文件用于描述 COM 类型和接口。对于了解 COM 和因此了解“传统” IDL 的人来说,语法会有些不同,因为在新版本中,语言已简化和修改,以支持 Windows Runtime 的类型。

在 Visual Studio 的解决方案中,我们选择 UWP 项目 `TicketMachine`;首先,我们将 `Class.idl` 文件重命名。我们选择一个具有代表性的名称。

注意:C++/WinRT 为每个 `.idl` 文件创建一个相应的 `.winmd` 文件,因此为了避免出现多个 `.winmd` 文件,我将在单个 `.idl` 文件中声明所有接口和类。这种技术是完全合法的,并且可以大大缩短复杂项目的构建时间。

在我们的示例中,接口和类将被(参见上面的注释)收集到一个 `.idl` 文件中;我将后者命名为 `Common.idl`。重命名 `.idl` 文件后,头文件和实现文件(分别为 `Class.h` 和 `Class.cpp`)会自动重命名。

重命名完这三个文件后,我们必须更正包含和类名,它们默认引用 Class。

我们继续第一次编译 `TicketMachine` 项目,从而创建 `TicketMachine.winmd` 和 `TicketMachine.dll` 的第一个版本(尽管目前是无用的)。

稍后我们将看到,在适当的时候,DLL 将在运行时加载(或者更确切地说,操作系统会为我们完成),通过它,我们将能够访问 Win32 应用程序中的 `.winmd` 文件中包含的元数据;事实上,由于目前无法(至少目前)直接导入到本机 Win32 应用程序中,因此 `.winmd` 文件中包含的类型是访问元数据的方式。如果你以为只需在 Visual Studio 中添加对本机 Win32 项目的引用就可以导入 `.winmd` 文件,那么当你尝试时,你就会改变主意,因为 Visual Studio 会用下面的警告来阻止你。

对示例 C++/WinRT 组件的简要分析

我们的示例项目将使我们能够从 C++/WinRT 的角度看到封装、继承和多态性的应用;我们将设计一个管理假设办公室柜台队列的 WinRT 组件,以及一个“消耗”它的 Win32 经典 C++ 客户端应用程序。

此外,在组件中,我们还将实现一些事件,这些事件可以被 UWP、.NET 等应用程序(如果将来可能实现的话)以及 Win32 客户端管理。

首先,我们确定涉及的实体:→ 服务 → 分支 → 操作员 → 票据终端 → 智能手机应用程序票据 → 等待队列操作 → 日志记录已完成的操作。

一些初始规范

  • → 操作员在每个工作日可以被分配到任何柜台。
  • → 每个操作员在其柜台可以执行所有服务。
  • → 对于队列中的每张票据,必须注明预计等待时间。
  • → 发放票据时必须触发一个等待开始事件。
  • → 操作完成后必须触发一个关闭操作事件。

根据以上信息,可以推断出应实现以下接口和类

  • 接口:
    • IServices 属性
    • IDesks
    • IOperators
    • ITickets
  • :
    • Service
    • Desk
    • 运算符
    • 工单
    • OperationsQueue
    • OperationsLog

我们用 UML 图表示我们打算开发的类之间的关系。

我们在 `Common.idl` 文件中定义接口和类

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

namespace TicketMachine
{
    //New type Date
    interface IDate
    {
    Int32 Year;
    Int32 Month;
    Int32 Day;    
    };

    //New type Time    
    interface ITime
    {
        Int32 Hh;
        Int32 Mm;
        Int32 Ss;    
    };
   
    unsealed runtimeclass Date:  IDate,ITime
    {
        Date();
        String DateToString{get; };
        String TimeToString{ get; };       
    };

    //Services
    interface IServices
    {
        String ServiceCode;
        String ServiceName;
    };

    runtimeclass Service : IServices, ICommon
    {
        Service();
        Windows.Foundation.IAsyncOperation<IVector<Service> > GetCollection{ get; };        
    }

    //Tickets
    interface IImageFiles
    {
        Windows.Storage.StorageFile ImageFile;
    };
   
    interface ITickets
    {
        String TicketNumber;
        String TicketBarcode;      
        Int32 MaxQueueItems;
        Date CreationDate;
        Windows.Storage.StorageFile TicketQRCode;
    };

    unsealed runtimeclass Ticket: ITickets, IImageFiles, ICommon,IServices,IDesks,IOperators
    {
        Ticket();
        void Create();
        String TicketToString{ get; };        
    }
    
    //Desks
    interface IDesks
    {
        String DeskNumber;
        String DeskCode;
        String DeskName;
    };

    runtimeclass Desk: IDesks, ICommon
    {
        Desk();
        Windows.Foundation.IAsyncOperation<IVector<Desk> > GetCollection{ get; };
    }

    //Operators
    interface IOperators
    {
        String FirstName;
        String LastName;
        Date BirthDate;
    };

    runtimeclass Operator : IOperators, ICommon
    {
        Operator();
        String BadgeCode;
        Windows.Foundation.IAsyncOperation<IVector<Operator> > GetCollection{ get; };
    }

    //Operations Queue
    [default_interface]
    unsealed runtimeclass OperationsQueue : IServices, IDesks, ITickets,ICommon
    {
        OperationsQueue();

        Windows.Foundation.IAsyncOperation<IVector<OperationsQueue> > GetCollection{ get; };

        //Events Methods
        void OperationItemAdded(Boolean isAdded);       
        void OperationCompleted(Boolean isCompleted);
       
        //Events
        event Windows.Foundation.EventHandler
              <TicketMachine.StartQueueEventArgs> OnQueueItemAdded;
        event Windows.Foundation.EventHandler
              <TicketMachine.CloseOperationEventArgs> OnOperationCompleted;
    };

    //Operations Log
    [default_interface]
    unsealed runtimeclass OperationsLog : IServices, ITickets, ICommon
    {
        OperationsLog();

        Windows.Foundation.IAsyncOperation<IVector<OperationsLog> > GetCollection{ get; };
    };

    interface ICommon
    {
        void Add();
        void Edit();
        void Delete();
        void Save();
    };

    [default_interface]
    unsealed runtimeclass Common: ICommon
    {
        Common();        
    }

    //Events
    runtimeclass StartQueueEventArgs
    {
        Boolean ItemAdded{get; };
    };

    runtimeclass CloseOperationEventArgs
    {
        Boolean OperationClosed{get; };
    };
}

我们构建 `TicketMachine` 项目,以便 Visual Studio 创建所有存根文件(`.h` 和 `.cpp`)。

现在我们打开 `TicketMachine` 项目的文件夹,并创建一个新文件夹,名称自定,我将其命名为 `Generated`。在此文件夹中,我们将复制 Visual Studio 在项目子文件夹 `..\\TicketMachine\\Generated Files\\sources` 中创建的所有文件(`.h` 和 `.cpp`),但排除 `Common.h` 和 `Common.cpp`。

然后在解决方案资源管理器生成文件过滤器中,我们右键单击 -> 添加 -> 现有项... 并添加新创建文件夹(在此示例中为 `Generated`)中的所有文件。

我们在 `Generated` 文件夹的所有文件(`.h` 和 `.cpp`)中注释掉以下行

static_assert(false, "Do not compile generated C++/WinRT source files directly");

编译 `TicketMachine` 项目,并确保 Visual Studio 生成了 `TicketMachine.winmd` 和 `TicketMachine.dll`。

很快,我们将看到如何在本机 Win32 应用程序中消耗我们的 WinRT 组件,但在此之前,让我们先在各自的类中实现属性、方法和事件。

我们将首先实现 `Date`、`Service`、`Operator`、`Desk` 和 `Ticket` 类。`Date` 类旨在实现两个新的数据类型(`Date` 和 `Time`);`Service`、`Operator` 和 `Ticket` 将分别提供服务、操作员和分支的静态列表;显然,在实际应用程序中,这些数据将来自数据库或 Web 服务。`Ticket` 类将用于(准确地)创建柜台预订的票据。

Date.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "Date.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct Date : DateT<Date>
    {
        Date() = default;

        hstring DateToString();
        hstring TimeToString();
        int32_t Year();
        void Year(int32_t value);
        int32_t Month();
        void Month(int32_t value);
        int32_t Day();
        void Day(int32_t value);
        int32_t Hh();
        void Hh(int32_t value);
        int32_t Mm();
        void Mm(int32_t value);
        int32_t Ss();
        void Ss(int32_t value);

    private:
        int32_t m_year{ 0 };
        int32_t m_month{ 0 };
        int32_t m_day{ 0 };
        int32_t m_hh{ 0 };
        int32_t m_mm{ 0 };
        int32_t m_ss{ 0 };

        hstring Format(int32_t t);
    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct Date : DateT<Date, implementation::Date>
    {
    };
}
////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "Date.h"
#include "Date.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    hstring Date::DateToString()
    {
        //throw hresult_not_implemented();
        hstring tmpDate = winrt::to_hstring(m_month) + L"/" + 
                          to_hstring(m_day)+L"/"+to_hstring(m_year);
        return tmpDate;
    }
    hstring Date::TimeToString()
    {
       // throw hresult_not_implemented();
        hstring tmpTime = L"";
        tmpTime =  Format(m_hh) + L":" + Format(m_mm) + L":" + Format(m_ss);
        return tmpTime;
    }

    hstring implementation::Date::Format(int32_t t)
    {
        hstring tmpTime = to_hstring(t);

        switch (tmpTime.size())
        {
        case 1:tmpTime = L"0" + tmpTime; break;
        }
        return tmpTime;
    }

    int32_t Date::Year()
    {
       // throw hresult_not_implemented();
        return m_year;
    }
    void Date::Year(int32_t value)
    {
        //throw hresult_not_implemented();
        m_year = value;
    }
    int32_t Date::Month()
    {
       // throw hresult_not_implemented();
        return m_month;
    }
    void Date::Month(int32_t value)
    {
        //throw hresult_not_implemented();
        m_month = value;
    }
    int32_t Date::Day()
    {
       //throw hresult_not_implemented();
        return m_day;
    }
    void Date::Day(int32_t value)
    {
        //throw hresult_not_implemented();
        m_day = value;
    }
    int32_t Date::Hh()
    {
        //throw hresult_not_implemented();
        return m_hh;
    }
    void Date::Hh(int32_t value)
    {
        //throw hresult_not_implemented();
        m_hh = value;
    }
    int32_t Date::Mm()
    {
        //throw hresult_not_implemented();
        return m_mm;
    }
    void Date::Mm(int32_t value)
    {
        //throw hresult_not_implemented();
        m_mm = value;
    }
    int32_t Date::Ss()
    {
        //throw hresult_not_implemented();
        return m_ss;
    }
    void Date::Ss(int32_t value)
    {
        //throw hresult_not_implemented();
        m_ss = value;
    }
}

Date.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "Date.h"
#include "Date.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
// static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    hstring Date::DateToString()
    {
        //throw hresult_not_implemented();
        hstring tmpDate = winrt::to_hstring(m_month) + L"/" + 
                          to_hstring(m_day)+L"/"+to_hstring(m_year);
        return tmpDate;
    }
    hstring Date::TimeToString()
    {
       // throw hresult_not_implemented();
        hstring tmpTime = L"";
        tmpTime =  Format(m_hh) + L":" + Format(m_mm) + L":" + Format(m_ss);
        return tmpTime;
    }

    hstring implementation::Date::Format(int32_t t)
    {
        hstring tmpTime = to_hstring(t);

        switch (tmpTime.size())
        {
        case 1:tmpTime = L"0" + tmpTime; break;
        }
        return tmpTime;
    }

    int32_t Date::Year()
    {
       // throw hresult_not_implemented();
        return m_year;
    }
    void Date::Year(int32_t value)
    {
        //throw hresult_not_implemented();
        m_year = value;
    }
    int32_t Date::Month()
    {
       // throw hresult_not_implemented();
        return m_month;
    }
    void Date::Month(int32_t value)
    {
        //throw hresult_not_implemented();
        m_month = value;
    }
    int32_t Date::Day()
    {
       //throw hresult_not_implemented();
        return m_day;
    }
    void Date::Day(int32_t value)
    {
        //throw hresult_not_implemented();
        m_day = value;
    }
    int32_t Date::Hh()
    {
        //throw hresult_not_implemented();
        return m_hh;
    }
    void Date::Hh(int32_t value)
    {
        //throw hresult_not_implemented();
        m_hh = value;
    }
    int32_t Date::Mm()
    {
        //throw hresult_not_implemented();
        return m_mm;
    }
    void Date::Mm(int32_t value)
    {
        //throw hresult_not_implemented();
        m_mm = value;
    }
    int32_t Date::Ss()
    {
        //throw hresult_not_implemented();
        return m_ss;
    }
    void Date::Ss(int32_t value)
    {
        //throw hresult_not_implemented();
        m_ss = value;
    }
}

Service.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "Service.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct Service : ServiceT<Service>
    {
        Service() = default;
       
        Windows::Foundation::IAsyncOperation
        <Windows::Foundation::Collections::IVector<TicketMachine::Service>> GetCollection();

        hstring ServiceCode();
        void ServiceCode(hstring const& value);
        hstring ServiceName();
        void ServiceName(hstring const& value);
        
       //Common
        void Add();
        void Edit();
        void Delete();
        void Save();

    private:       
        hstring m_serviceCode{ L"" };
        hstring m_serviceName{ L"" };
        Windows::Foundation::Collections::IVector<TicketMachine::Service> m_services;
    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct Service : ServiceT<Service, implementation::Service>
    {
    };
}

Service.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "Service.h"
#include "Service.g.cpp"

#include <winrt/Windows.Foundation.Collections.h>

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    
    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector
                         <TicketMachine::Service>> Service::GetCollection()
    {
        winrt::TicketMachine::Service srv[4];
       
        m_services = winrt::single_threaded_vector<winrt::TicketMachine::Service>();

        int i = 0;
        while (i <= 4)
        {
            srv[i] = winrt::make<winrt::TicketMachine::implementation::Service>();

            switch (i)
            {
            case 0: srv[i].ServiceCode(L"01");
                    srv[i].ServiceName(L"Currency Exchanges"); 
                    break;
            case 1: srv[i].ServiceCode(L"02");
                    srv[i].ServiceName(L"Front Desk Customer Service"); 
                    break;
            case 2: srv[i].ServiceCode(L"03");
                    srv[i].ServiceName(L"Computer&Smartphone Assistance"); 
                    break;
            case 3: srv[i].ServiceCode(L"04");
                    srv[i].ServiceName(L"Lost&Found"); 
                    break;
            case 4: srv[i].ServiceCode(L"05");
                    srv[i].ServiceName(L"Parking"); 
                    break;
            }

            m_services.Append(srv[i]);

            ++i;
        }

       co_return m_services;
    }

    hstring Service::ServiceCode()
    {
        return m_serviceCode;
    }
    void Service::ServiceCode(hstring const& value)
    {
         m_serviceCode = value;
    }
    hstring Service::ServiceName()
    {
        return m_serviceName;
    }
    void Service::ServiceName(hstring const& value)
    {
        m_serviceName = value;
    }
    void Service::Add()
    {
        //throw hresult_not_implemented();
    }
    void Service::Edit()
    {
        //throw hresult_not_implemented();
    }
    void Service::Delete()
    {
        //throw hresult_not_implemented();
    }
    void Service::Save()
    {
        //throw hresult_not_implemented();
    }
}

Operator.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "Operator.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct Operator : OperatorT<Operator>
    {
        Operator() = default;

        hstring BadgeCode();
        void BadgeCode(hstring const& value);
        Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector
                             <TicketMachine::Operator>> GetCollection();
        hstring FirstName();
        void FirstName(hstring const& value);
        hstring LastName();
        void LastName(hstring const& value);
        TicketMachine::Date BirthDate();
        void BirthDate(TicketMachine::Date const& value);

        //Common
        void Add();
        void Edit();
        void Delete();
        void Save();

    private:
        hstring m_badgeCode{ L"" };
        hstring m_firstName{ L"" };
        hstring m_lastName{ L"" };
        TicketMachine::Date m_birthDate;
        Windows::Foundation::Collections::IVector<TicketMachine::Operator> m_operators;
    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct Operator : OperatorT<Operator, implementation::Operator>
    {
    };
}

Operator.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "Operator.h"
#include "Operator.g.cpp"

#include <winrt/Windows.Foundation.Collections.h>

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    hstring Operator::BadgeCode()
    {
        return m_badgeCode;
    }
    void Operator::BadgeCode(hstring const& value)
    {
        m_badgeCode = value;
    }    
    
    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector
                         <TicketMachine::Operator>> Operator::GetCollection()
    {
        winrt::TicketMachine::Operator opr[4];
        m_operators = winrt::single_threaded_vector<winrt::TicketMachine::Operator>();

        int i = 0;
        while (i <= 4)
        {
            opr[i] = winrt::make<winrt::TicketMachine::implementation::Operator>();

            switch (i)
            {
            case 0:  opr[i].BadgeCode(L"8C8882D9-5BDE-4FDA-86C7-DB9926DB75AE");
                     opr[i].FirstName(L"Mario");
                     opr[i].LastName(L"Rossi");
                     m_birthDate.Year(2001); m_birthDate.Month(12); m_birthDate.Day(10);
                     opr[i].BirthDate(m_birthDate);
                     break;

            case 1:  opr[i].BadgeCode(L"441661CA-9A44-4B6A-AA4B-B99B13F4C214");
                     opr[i].FirstName(L"Franco");
                     opr[i].LastName(L"Verdi");
                     m_birthDate.Year(1976); m_birthDate.Month(4); m_birthDate.Day(22);
                     opr[i].BirthDate(m_birthDate);
                     break;

            case 2:  opr[i].BadgeCode(L"1F10AFF3-4365-445B-B256-AFFA2CCC8BF7");
                     opr[i].FirstName(L"Gianna");
                     opr[i].LastName(L"Gialli");
                     m_birthDate.Year(1985); m_birthDate.Month(5); m_birthDate.Day(31);
                     opr[i].BirthDate(m_birthDate);
                     break;

            case 3:  opr[i].BadgeCode(L"FE1F901F-6BBF-45F0-8885-DE049153FFD0");
                     opr[i].FirstName(L"Maria");
                     opr[i].LastName(L"Bianchi");
                     m_birthDate.Year(1998); m_birthDate.Month(12); m_birthDate.Day(19);
                     opr[i].BirthDate(m_birthDate);
                     break;

            case 4:  opr[i].BadgeCode(L"C3D6F5F7-7981-433B-8A7E-61DD6AF8735E");
                     opr[i].FirstName(L"Rosa");
                     opr[i].LastName(L"Neri");
                     m_birthDate.Year(1990); m_birthDate.Month(2); m_birthDate.Day(22);
                     opr[i].BirthDate(m_birthDate);
                     break;
            }

            m_operators.Append(opr[i]);

            ++i;
        }

        co_return m_operators;
    }
    hstring Operator::FirstName()
    {
        return m_firstName;
    }
    void Operator::FirstName(hstring const& value)
    {
        m_firstName = value;
    }
    hstring Operator::LastName()
    {
        return m_lastName;
    }
    void Operator::LastName(hstring const& value)
    {
        m_lastName = value;
    }
    TicketMachine::Date Operator::BirthDate()
    {
        return m_birthDate;
    }
    void Operator::BirthDate(TicketMachine::Date const& value)
    {
        m_birthDate = value;
    }
    void Operator::Add()
    {
        //throw hresult_not_implemented();
    }
    void Operator::Edit()
    {
        //throw hresult_not_implemented();
    }
    void Operator::Delete()
    {
        //throw hresult_not_implemented();
    }
    void Operator::Save()
    {
        //throw hresult_not_implemented();
    }
}

Desk.h

    
////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "Desk.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct Desk : DeskT<Desk>
    {
        Desk() = default;

        Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::IVector
                             <TicketMachine::Desk>> GetCollection();
        hstring DeskNumber();
        void DeskNumber(hstring const& value);
        hstring DeskCode();
        void DeskCode(hstring const& value);
        hstring DeskName();
        void DeskName(hstring const& value);

        //Common
        void Add();
        void Edit();
        void Delete();
        void Save();

    private:
        hstring m_deskNumber{ L"" };
        hstring m_deskCode{ L"" };
        hstring m_deskName {L"" };
        Windows::Foundation::Collections::IVector<TicketMachine::Desk> m_desks;

    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct Desk : DeskT<Desk, implementation::Desk>
    {
    };
}

Desk.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "Desk.h"
#include "Desk.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    Windows::Foundation::IAsyncOperation$lt;Windows::Foundation::Collections::IVector
                         <TicketMachine::Desk>> Desk::GetCollection()
    {
        winrt::TicketMachine::Desk dsk[4];
        m_desks = winrt::single_threaded_vector<winrt::TicketMachine::Desk>();

        int i = 0;
        while (i <= 4)
        {
            dsk[i] = winrt::make<winrt::TicketMachine::implementation::Desk>();

            switch (i)
            {

            case 0: dsk[i].DeskNumber(L"1");
                    dsk[i].DeskCode(L"A");
                    dsk[i].DeskName(L"A01");
                    break;

            case 1: dsk[i].DeskNumber(L"2");
                    dsk[i].DeskCode(L"B");
                    dsk[i].DeskName(L"B02");
                    break;

            case 2: dsk[i].DeskNumber(L"3");
                    dsk[i].DeskCode(L"C");
                    dsk[i].DeskName(L"C03");
                    break;

            case 3: dsk[i].DeskNumber(L"4");
                    dsk[i].DeskCode(L"D");
                    dsk[i].DeskName(L"D04");
                    break;

            case 4: dsk[i].DeskNumber(L"5");
                    dsk[i].DeskCode(L"E");
                    dsk[i].DeskName(L"E05");
                    break;
            }

            m_desks.Append(dsk[i]);

            ++i;
        }

        co_return m_desks;
    }
    hstring Desk::DeskNumber()
    {
        return m_deskNumber;
    }
    void Desk::DeskNumber(hstring const& value)
    {
        m_deskNumber = value;
    }
    hstring Desk::DeskCode()
    {
        return m_deskCode;
    }
    void Desk::DeskCode(hstring const& value)
    {
        m_deskCode = value;
    }
    hstring Desk::DeskName()
    {
        return m_deskName;
    }
    void Desk::DeskName(hstring const& value)
    {
        m_deskName = value;
    }

    void Desk::Add()
    {
       // throw hresult_not_implemented();
    }
    void Desk::Edit()
    {
        //throw hresult_not_implemented();
    }
    void Desk::Delete()
    {
        //throw hresult_not_implemented();
    }
    void Desk::Save()
    {
        //throw hresult_not_implemented();
    }
}

Ticket.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "Ticket.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct Ticket : TicketT<Ticket>
    {
        Ticket() = default;

        void Create();
        hstring TicketNumber();
        void TicketNumber(hstring const& value);
        hstring TicketBarcode();
        void TicketBarcode(hstring const& value);
        int32_t MaxQueueItems();
        void MaxQueueItems(int32_t value);
        TicketMachine::Date CreationDate();
        void CreationDate(TicketMachine::Date const& value);
        Windows::Storage::StorageFile TicketQRCode();
        void TicketQRCode(Windows::Storage::StorageFile const& value);
        Windows::Storage::StorageFile ImageFile();
        void ImageFile(Windows::Storage::StorageFile const& value);
        hstring TicketToString();

        //Common
        void Add();
        void Edit();
        void Delete();
        void Save();

        //Services
        hstring ServiceCode();
        void ServiceCode(hstring const& value);
        hstring ServiceName();
        void ServiceName(hstring const& value);

        //Desks
        hstring DeskNumber();
        void DeskNumber(hstring const& value);
        hstring DeskCode();
        void DeskCode(hstring const& value);
        hstring DeskName();
        void DeskName(hstring const& value);

        //Operators
        hstring FirstName();
        void FirstName(hstring const& value);
        hstring LastName();
        void LastName(hstring const& value);
        TicketMachine::Date BirthDate();
        void BirthDate(TicketMachine::Date const& value);

    private:
       
        hstring m_ticketNumber{ L"" };
        hstring m_ticketBarcode{ L"" };
        int32_t m_maxQueueElements{ 100 };
        winrt::TicketMachine::Date m_creationDate;

        winrt::TicketMachine::Service m_service;
        winrt::TicketMachine::Desk m_desk;
        winrt::TicketMachine::Operator m_operator;

        int m_index = 0;

        hstring m_ticketString = L"";       

        //Services
        hstring m_serviceCode{ L"" };
        hstring m_serviceName{ L"" };

        //Desks
        hstring m_deskNumber{ L"" };
        hstring m_deskCode{ L"" };
        hstring m_deskName{ L"" };

        //Operators
        hstring m_badgeCode{ L"" };
        hstring m_firstName{ L"" };
        hstring m_lastName{ L"" };
        TicketMachine::Date m_birthDate;

        TicketMachine::Date GetDate();
    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct Ticket : TicketT<Ticket, implementation::Ticket>
    {
    };
}

Ticket.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "Ticket.h"
#include "Ticket.g.cpp"

#include "Helpers.h"
#include <ctime>

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;
// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{       
    void Ticket::Create()
    {
        // Get Services
        winrt::TicketMachine::Service srv;
        Collection<winrt::TicketMachine::Service> _srv;
        
        auto _services = _srv.GetItems(srv,true);        
        //===========================

        // Get Desks
        winrt::TicketMachine::Desk dsk;
        Collection<winrt::TicketMachine::Desk> _dsk;

        auto _desks = _dsk.GetItems(dsk, true);
        //===========================

        // Get Operators
        winrt::TicketMachine::Operator opr;
        Collection<winrt::TicketMachine::Operator> _opr;

        auto _operators = _opr.GetItems(opr, true);
        //===========================

        //Check ticket number        
        if (m_index > m_maxQueueElements)
            m_index = 1;
        else
            m_index += 1;

        //Set current ticket index
        TicketNumber(winrt::to_hstring(m_index));        
        
        //Ticket combinations
        int rnd = rand() % 5;

        hstring tmpTicket = _services[rnd].ServiceCode() + L", " +
                            _services[rnd].ServiceName() + L", " +
                            _desks[rnd].DeskNumber()     + L", " +
                            _desks[rnd].DeskCode()       + L", " +
                            _desks[rnd].DeskName()       + L", " +
                            _operators[rnd].BadgeCode()  + L", " +
                            _operators[rnd].FirstName()  + L", " +
                            _operators[rnd].LastName()   + L", " +
                            _operators[rnd].BirthDate().DateToString()  + L", ";
        
        m_creationDate = GetDate();

        //Service 
        m_serviceCode = _services[rnd].ServiceCode();
        m_serviceName = _services[rnd].ServiceName();

        //Desk
        m_deskNumber = _desks[rnd].DeskNumber();
        m_deskCode = _desks[rnd].DeskCode();
        m_deskName = _desks[rnd].DeskName();
        
        //Operator
        m_badgeCode = _operators[rnd].BadgeCode();
        m_firstName = _operators[rnd].FirstName();
        m_lastName =  _operators[rnd].LastName();
        m_birthDate = _operators[rnd].BirthDate();

        //Set current ticket code
        m_ticketString = tmpTicket;
    }

    TicketMachine::Date implementation::Ticket::GetDate()
    {
        std::time_t t = std::time(0);
        struct tm date;
        _localtime64_s(&date, &t);

        int year = date.tm_year + 1900;
        int month = date.tm_mon + 1;
        int day = date.tm_mday;

        int hour = date.tm_hour;
        int minutes = date.tm_min;
        int seconds = date.tm_sec;

        TicketMachine::Date dt;

        dt.Year(year);
        dt.Month(month);
        dt.Day(day);

        dt.Hh(hour);
        dt.Mm(minutes);
        dt.Ss(seconds);

        return dt;        
    }

    hstring Ticket::TicketToString()
    {
        return m_ticketString;
    }

    hstring Ticket::TicketNumber()
    {
        return m_ticketNumber;
    }
    void Ticket::TicketNumber(hstring const& value)
    {
        m_ticketNumber = value;
    }
    hstring Ticket::TicketBarcode()
    {
        return m_ticketBarcode;
    }
    void Ticket::TicketBarcode(hstring const& value)
    {
        m_ticketBarcode = value;
    }
    int32_t Ticket::MaxQueueItems()
    {
        return m_maxQueueElements;
    }
    void Ticket::MaxQueueItems(int32_t value)
    {
        m_maxQueueElements = value;
    }
    TicketMachine::Date Ticket::CreationDate()
    {
        return m_creationDate;
    }
    void Ticket::CreationDate(TicketMachine::Date const& value)
    {
        m_creationDate = value;
    }
    Windows::Storage::StorageFile Ticket::TicketQRCode()
    {
        //throw hresult_not_implemented();
        return nullptr;
    }
    void Ticket::TicketQRCode(Windows::Storage::StorageFile const& /*value*/)
    {
        //throw hresult_not_implemented();
    }
    Windows::Storage::StorageFile Ticket::ImageFile()
    {
        //throw hresult_not_implemented();
        return nullptr;
    }
    void Ticket::ImageFile(Windows::Storage::StorageFile const& /*value*/)
    {
        //throw hresult_not_implemented();
    }
    
    //Common
    void Ticket::Add()
    {
        //throw hresult_not_implemented();
    }
    void Ticket::Edit()
    {
        //throw hresult_not_implemented();
    }
    void Ticket::Delete()
    {
        //throw hresult_not_implemented();
    }
    void Ticket::Save()
    {
        //throw hresult_not_implemented();
    }

    //Services
    hstring Ticket::ServiceCode()
    {
        return m_serviceCode;
    }
    void Ticket::ServiceCode(hstring const& value)
    {
        m_serviceCode = value;
    }
    hstring Ticket::ServiceName()
    {
        return m_serviceName;
    }
    void Ticket::ServiceName(hstring const& value)
    {
        m_serviceName = value;
    }

    //Desks
    hstring Ticket::DeskNumber()
    {
        return m_deskNumber;
    }
    void Ticket::DeskNumber(hstring const& value)
    {
        m_deskNumber = value;
    }
    hstring Ticket::DeskCode()
    {
        return m_deskCode;
    }
    void Ticket::DeskCode(hstring const& value)
    {
        m_deskCode = value;
    }
    hstring Ticket::DeskName()
    {
        return m_deskName;
    }
    void Ticket::DeskName(hstring const& value)
    {
        m_deskName = value;
    }

    //Operators
    hstring Ticket::FirstName()
    {
        return m_firstName;
    }
    void Ticket::FirstName(hstring const& value)
    {
        m_firstName = value;
    }
    hstring Ticket::LastName()
    {
        return m_lastName;
    }
    void Ticket::LastName(hstring const& value)
    {
        m_lastName = value;
    }
    TicketMachine::Date Ticket::BirthDate()
    {
        return m_birthDate;
    }
    void Ticket::BirthDate(TicketMachine::Date const& value)
    {
        m_birthDate = value;
    }
}

当需要创建新票据时,消耗该组件的应用程序必须在 `Ticket.cpp` 文件中的 `Create` 方法中调用。

创建后,它将排入任何其他待处理票据的队列,为此我们将实现 `OperationsQueue` 类。

每张票据在柜台操作完成后,将被插入到另一个区域(在实际应用程序中在数据库等中),我们将在其中用 `OperationsLog` 类表示。

如果我们分析 `Create` 方法,我们可以看到 `Collection` 类被实例化了好几次。

这个模板类的目的是创建一个列表

  • 服务
  • 柜台
  • 运算符

并将它们(如果需要)以伪随机的方式关联起来。因此,每次执行 `Create` 方法时,我们都会得到服务、柜台和操作员的不同组合。

这个机制在运行时将模拟出票据发放终端的功能。`Collection` 模板类位于 `Helpers.h` 的 `include` 文件中。

Helpers.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "pch.h"
#include <vector>
#include <algorithm>
#include <deque>
#include <list>
#include <set>
#include <map>
#include <string>
#include <functional>
#include <numeric>
#include <random>
#include <chrono>
#include <ppltasks.h >

template <typename T>
inline void CreateIntegerRange(T& _vector, int min, int max)
{
	int index = min;
	do
	{

		_vector.insert(_vector.end(), index);
		++index;
	} while (index <= max);
}

template <typename T>
class RandomOrder
{
public:

	RandomOrder() = delete;

	virtual ~RandomOrder()
	{
		m_vector.clear();

	}

	RandomOrder(std::vector<T> D)
	{
		unsigned seed = (unsigned)std::chrono::system_clock::now().time_since_epoch().count();

		std::shuffle(D.begin(), D.end(), std::default_random_engine(seed));

		m_vector = D;
	}

	std::vector<T> get()
	{
		return m_vector;
	}
private:
	std::vector<T> m_vector;
	
};

template <typename I>
class Collection
{
public:
	Collection() = default;
	
	winrt::Windows::Foundation::Collections::IVectorView<I> 
    GetView(winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Foundation::
    Collections::IVector<I>> items)
	{
		return Concurrency::create_task([items] {
			return  items.get().GetView();
			}).get();
	}

   std::vector<I> GetItems(I const& E,  bool shuffle)
	{		
	   winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::
       Foundation::Collections::IVector<I>> items = E.GetCollection(); 
	   winrt::Windows::Foundation::Collections::IVectorView<I> viewItems = GetView(items);

	   std::vector<I> _items;

		int i = 0;
		int elements = viewItems.Size();
		do
		{
			_items.push_back(viewItems.GetAt(i));
			++i;
		} while (i <= (elements - 1));
		
		if (shuffle)
		{
			RandomOrder<I> rdrItems(_items);
			return rdrItems.get();
		}

		else
			return _items;
	}
};

C++/WinRT 组件中的事件

众所周知,一般来说,类中的事件是通知使用该类的应用程序“发生了某事”(例如:单击按钮、文件下载完成等)的方式。在 C++/WinRT 中,事件被声明为委托类型,并且必须注册才能被管理;最后,当不再使用时,可以将其撤销。

根据具体情况,事件可以声明为以下委托类型之一

  • winrt::d bound
  • winrt::event

当事件不需要“与外部”通信时,我们将使用 `winrt::d ebound` 类型;相反,当事件必须可以通过 ABI(应用程序二进制接口)访问时,也就是说,当 WinRT 组件和消耗它的应用程序都可以访问事件时,我们将使用 `winrt::event`。

同样众所周知的是,事件可以带有参数。

对于 `winrt::d` elegated 类型,参数不必严格为 Windows Runtime 类型,可以是 Windows Runtime 类型或自定义类型。相反,对于 `winrt::event` 类型,参数只能是 Windows Runtime 类型或原始类型(`int`、`float` 等)。现在,由于我们的 `TicketMachine` 组件的事件必须“通过”ABI,我们在 `Common.idl` 文件中的 Operations queue 类中声明了两个 `winr::event` 类型的事件,它们的参数都是 `bool` 类型

第一个事件将在发出新票据时调用,第二个事件将在操作完成后调用。

Common.idl

.............................
.............................
.............................

//Event Methods
void OperationItemAdded(Boolean isAdded);       
void OperationCompleted(Boolean isCompleted);
       
//Events
event Windows.Foundation.EventHandler<TicketMachine.StartQueueEventArgs> OnQueueItemAdded;
event Windows.Foundation.EventHandler<TicketMachine.CloseOperationEventArgs> OnOperationCompleted;

接下来是类的声明和实现

  • OperationsQueue
  • OperationsLog
  • StartQueueEventArgs
  • CloseOperationEventArgs 属性

OperationsQueue.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "OperationsQueue.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct OperationsQueue : OperationsQueueT<OperationsQueue>
    {
        OperationsQueue() = default;

        Windows::Foundation::IAsyncOperation<Windows::Foundation::
        Collections::IVector<TicketMachine::OperationsQueue>> GetCollection();

        //Event Methods and handlers:

        //Event methods
        void OperationItemAdded(bool isAdded);
        void OperationCompleted(bool isCompleted);

        //Event handlers
        winrt::event_token OnQueueItemAdded(Windows::Foundation::EventHandler
               <TicketMachine::StartQueueEventArgs> const& handler);
        winrt::event_token OnOperationCompleted(Windows::Foundation::EventHandler
               <TicketMachine::CloseOperationEventArgs> const& handler);

        //Register/Revoke events
        void OnQueueItemAdded(winrt::event_token const& token) noexcept;
        void OnOperationCompleted(winrt::event_token const& token) noexcept;

        //Services
        hstring ServiceCode();
        void ServiceCode(hstring const& value);
        hstring ServiceName();
        void ServiceName(hstring const& value);

        //Desks
        hstring DeskNumber();
        void DeskNumber(hstring const& value);
        hstring DeskCode();
        void DeskCode(hstring const& value);
        hstring DeskName();
        void DeskName(hstring const& value);

        //Ticket
        hstring TicketNumber();
        void TicketNumber(hstring const& value);
        hstring TicketBarcode();
        void TicketBarcode(hstring const& value);
        int32_t MaxQueueItems();
        void MaxQueueItems(int32_t value);
        TicketMachine::Date CreationDate();
        void CreationDate(TicketMachine::Date const& value);
        Windows::Storage::StorageFile TicketQRCode();
        void TicketQRCode(Windows::Storage::StorageFile const& value);

        //Common
        void Add();
        void Edit();
        void Delete();
        void Save();

    private:
        hstring m_serviceCode{ L"" },
                m_serviceName{ L"" },
                m_deskCode{ L"" },
                m_deskName{ L"" },
                m_deskNumber{ L"" },
                m_ticketNumber{ L"" };

        int32_t m_maxQueueItems{ 0 };
        TicketMachine::Date m_CreationDate;

        winrt::event<Windows::Foundation::EventHandler<StartQueueEventArgs>> m_OnStartQueueEvent;
        bool m_startQueue = false;

        winrt::event<Windows::Foundation::EventHandler>CloseOperationEventArgs<< 
                                                       m_OnCompletedEvent;
        bool m_completed = false;
    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct OperationsQueue : OperationsQueueT<OperationsQueue, implementation::OperationsQueue>
    {
    };
}

OperationsQueue.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "OperationsQueue.h"
#include "OperationsQueue.g.cpp"
#include "StartQueueEventArgs.h"
#include "CloseOperationEventArgs.h"
#include "Helpers.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::
             IVector<TicketMachine::OperationsQueue>> OperationsQueue::GetCollection()
    {       
        return nullptr;
    }

    //Events
    void OperationsQueue::OperationItemAdded(bool isAdded)
    {
        m_startQueue = isAdded;
        auto args = winrt::make_self<winrt::TicketMachine::implementation::
                    StartQueueEventArgs>(m_startQueue);
        m_OnStartQueueEvent(*this, *args);
    }

    void OperationsQueue::OperationCompleted(bool isCompleted)
    {
        m_completed = isCompleted;
        auto args = winrt::make_self<winrt::TicketMachine::implementation::
                    CloseOperationEventArgs>(m_completed);
        m_OnCompletedEvent(*this, *args);
    }

    winrt::event_token OperationsQueue::OnQueueItemAdded(Windows::Foundation::
           EventHandler<ticketmachine::startqueueeventargs> const& handler)
    {
        return  m_OnStartQueueEvent.add(handler);
    }
    void OperationsQueue::OnQueueItemAdded(winrt::event_token const& token) noexcept
    {
        m_OnStartQueueEvent.remove(token);
    }

    winrt::event_token OperationsQueue::OnOperationCompleted
    (Windows::Foundation::EventHandler<ticketmachine::closeoperationeventargs> const& handler)
    {
       return m_OnCompletedEvent.add(handler);
    }
    void OperationsQueue::OnOperationCompleted(winrt::event_token const& token) noexcept
    {
        m_OnCompletedEvent.remove(token);
    }

    //Service
    hstring OperationsQueue::ServiceCode()
    {
        return m_serviceCode;
    }
    void OperationsQueue::ServiceCode(hstring const& value)
    {
        m_serviceCode = value;
    }
    hstring OperationsQueue::ServiceName()
    {
        return m_serviceName;
    }
    void OperationsQueue::ServiceName(hstring const& value)
    {
        m_serviceName = value;
    }

    //Desk
    hstring OperationsQueue::DeskNumber()
    {
        return m_deskNumber;
    }
    void OperationsQueue::DeskNumber(hstring const& value)
    {
        m_deskNumber = value;
    }
    hstring OperationsQueue::DeskCode()
    {
        return m_deskCode;
    }
    void OperationsQueue::DeskCode(hstring const& value)
    {
        m_deskCode = value;
    }
    hstring OperationsQueue::DeskName()
    {
        return m_deskName;
    }
    void OperationsQueue::DeskName(hstring const& value)
    {
        m_deskName = value;
    }

    //Ticket
    hstring OperationsQueue::TicketNumber()
    {
        return m_ticketNumber;
    }
    void OperationsQueue::TicketNumber(hstring const& value)
    {
        m_ticketNumber = value;
    }
    hstring OperationsQueue::TicketBarcode()
    {
        return L"";
    }
    void OperationsQueue::TicketBarcode(hstring const& /*value*/)
    {

    }
    int32_t OperationsQueue::MaxQueueItems()
    {
        return m_maxQueueItems;
    }
    void OperationsQueue::MaxQueueItems(int32_t value)
    {
        m_maxQueueItems = value;
    }
    TicketMachine::Date OperationsQueue::CreationDate()
    {
        return m_CreationDate;
    }
    void OperationsQueue::CreationDate(TicketMachine::Date const& value)
    {
        m_CreationDate = value;
    }
    Windows::Storage::StorageFile OperationsQueue::TicketQRCode()
    {
        return nullptr;
    }
    void OperationsQueue::TicketQRCode(Windows::Storage::StorageFile const& /*value*/)
    {

    }

    //Common
    void OperationsQueue::Add()
    {
        //throw hresult_not_implemented();
    }
    void OperationsQueue::Edit()
    {
        //throw hresult_not_implemented();
    }
    void OperationsQueue::Delete()
    {
        //throw hresult_not_implemented();
    }
    void OperationsQueue::Save()
    {
        //throw hresult_not_implemented();
    }
}</ticketmachine::closeoperationeventargs></ticketmachine::startqueueeventargs>

OperationsLog.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "OperationsLog.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct OperationsLog : OperationsLogT<operationslog>
    {
        OperationsLog() = default;

        Windows::Foundation::IAsyncOperation<Windows::Foundation::
        Collections::IVector<TicketMachine::OperationsLog>> GetCollection();

        //Service
        hstring ServiceCode();
        void ServiceCode(hstring const& value);
        hstring ServiceName();
        void ServiceName(hstring const& value);

        //Ticket
        hstring TicketNumber();
        void TicketNumber(hstring const& value);
        hstring TicketBarcode();
        void TicketBarcode(hstring const& value);
        int32_t MaxQueueItems();
        void MaxQueueItems(int32_t value);
        TicketMachine::Date CreationDate();
        void CreationDate(TicketMachine::Date const& value);
        Windows::Storage::StorageFile TicketQRCode();
        void TicketQRCode(Windows::Storage::StorageFile const& value);

        //Common
        void Add();
        void Edit();
        void Delete();
        void Save();

    private:
        hstring m_serviceCode{ L"" },
            m_serviceName{ L"" },
            m_deskCode{ L"" },
            m_deskName{ L"" },
            m_deskNumber{ L"" },
            m_ticketNumber{ L"" };

        int32_t m_maxQueueItems{ 0 };
        TicketMachine::Date m_CreationDate;
    };
}
namespace winrt::TicketMachine::factory_implementation
{
    struct OperationsLog : OperationsLogT<OperationsLog, implementation::OperationsLog>
    {
    };
}
    
</operationslog>

OperationsLog.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "OperationsLog.h"
#include "OperationsLog.g.cpp"
#include "Helpers.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    Windows::Foundation::IAsyncOperation<Windows::Foundation::Collections::
             IVector<TicketMachine::OperationsLog>> OperationsLog::GetCollection()
    {
        return nullptr;
    }

    hstring OperationsLog::ServiceCode()
    {
        return m_serviceCode;
    }
    void OperationsLog::ServiceCode(hstring const& value)
    {
        m_serviceCode = value;
    }
    hstring OperationsLog::ServiceName()
    {
        return m_serviceName;
    }
    void OperationsLog::ServiceName(hstring const& value)
    {
        m_serviceName = value;
    }
    hstring OperationsLog::TicketNumber()
    {
        return m_ticketNumber;
    }
    void OperationsLog::TicketNumber(hstring const& value)
    {
        m_ticketNumber = value;
    }
    hstring OperationsLog::TicketBarcode()
    {
        return L"";
    }
    void OperationsLog::TicketBarcode(hstring const& /*value*/)
    {

    }
    int32_t OperationsLog::MaxQueueItems()
    {
        return m_maxQueueItems;
    }
    void OperationsLog::MaxQueueItems(int32_t value)
    {
        m_maxQueueItems = value;
    }
    TicketMachine::Date OperationsLog::CreationDate()
    {
        return m_CreationDate;
    }
    void OperationsLog::CreationDate(TicketMachine::Date const& value)
    {
        m_CreationDate = value;
    }
    Windows::Storage::StorageFile OperationsLog::TicketQRCode()
    {
        return nullptr;
    }
    void OperationsLog::TicketQRCode(Windows::Storage::StorageFile const& /*value*/)
    {

    }
    void OperationsLog::Add()
    {
       // throw hresult_not_implemented();
    }
    void OperationsLog::Edit()
    {
       // throw hresult_not_implemented();
    }
    void OperationsLog::Delete()
    {
        //throw hresult_not_implemented();
    }
    void OperationsLog::Save()
    {
        //throw hresult_not_implemented();
    }
}

StartQueueEventArgs.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "StartQueueEventArgs.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct StartQueueEventArgs : StartQueueEventArgsT<StartQueueEventArgs>
    {
        StartQueueEventArgs() = default;

        bool ItemAdded();

        StartQueueEventArgs(bool isAdded);

       private:
           bool m_added = false;
    };
}

StartQueueEventArgs.cpp

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "StartQueueEventArgs.h"
#include "StartQueueEventArgs.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    bool StartQueueEventArgs::ItemAdded()
    {
        return m_added;
    }

    StartQueueEventArgs::StartQueueEventArgs(bool isAdded) :m_added(isAdded)
    {
        m_added = isAdded;
    }
}

CloseOperationEventArgs.h

////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#pragma once
#include "CloseOperationEventArgs.g.h"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    struct CloseOperationEventArgs : CloseOperationEventArgsT<CloseOperationEventArgs>
    {
        CloseOperationEventArgs() = default;

        bool OperationClosed();

        CloseOperationEventArgs(bool isClosed);

    private:
        bool m_closed = false;
    };
}

CloseOperationEventArgs.cpp

    
////====================================================================
//                          TicketMachine 
//                          C++/WinRT Component 
//
//                          Copyright (C) 2021
//                          G.Pischedda, all rights reserved
//                          software-on-demand-ita.com
////=====================================================================

#include "pch.h"
#include "CloseOperationEventArgs.h"
#include "CloseOperationEventArgs.g.cpp"

// Note: Remove this static_assert after copying these generated source files to your project.
// This assertion exists to avoid compiling these generated source files directly.
//static_assert(false, "Do not compile generated C++/WinRT source files directly");

namespace winrt::TicketMachine::implementation
{
    bool CloseOperationEventArgs::OperationClosed()
    {
        return m_closed;
    }

    implementation::CloseOperationEventArgs::CloseOperationEventArgs(bool isClosed)
    {
        m_closed = isClosed;
    }
}

组件已准备就绪,我们编译项目并生成更新后的 `TicketMachine.dll` 和 `TicketMachine.winmd`。

接下来的(也是本教程的最后一部分)中,我们将看到如何在 Win32 C++ 应用程序中消耗 C++/WinRT 组件。

转到 第 4 部分。实现演示 C++ Win32 应用程序

历史

  • 2022 年 1 月 14 日:初始版本
C++/WinRT 运行时组件在 Win32 应用程序中 - 第三部分 - CodeProject - 代码之家
© . All rights reserved.