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





5.00/5 (2投票s)
如何创建一个“消耗” 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` 文件:更具体地说,我们找到三个文件
- Class.idl
- Class.h
- 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 组件。
历史
- 2022 年 1 月 14 日:初始版本