Click here to Skip to main content
15,179,951 members
Articles / Programming Languages / C++17
Article
Posted 14 Jan 2022

Stats

1.7K views
35 downloads
2 bookmarked

C++/WinRT Runtime Component in Win32 Applications - Part 3

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
14 Jan 2022CPOL10 min read
How to create a Win32 C++ Application that "consumes" a C++/WinRT Component Runtime
In this article, you will learn to create a Win32 application in C++ that consumes a C++/WinRT component runtime.

Introduction

Note: In the same Visual Studio solution, we will create a C++/WinRT Runtime Component project in which we will implement runtime classes and a Win32 C++ Classic app project that will use them. For the Win32 classic app, I will use a Project Template for Visual Studio 2019 based on the homonymous C++ framework for Win32: Win32Framework, in its version with Ribbon that often, myself and my team, we use as a starting point for Win32 C++ apps as it simplifies and speeds up the work. (the Project Template and the Win32Framework are both my creation and distributed exclusively within my C++ team, it is not excluded, however, that in the future I may release a version of the Win32Framework on this website or on GitHub).

Of course, Win32Framework is not an obligatory requirement and you are obviously free to use the type of C++ project that best suits you, as long as it is based on the C++ standard 17.

The first step will then be to create a new C++ project in Visual Studio 2019.

Note: In this tutorial, you used Visual Studio 2019 vers. 16.8.x.

We choose a meaningful name for the new project, I chose UWPWin32Demo, and created its folder with the same name.

Image 1

Image 2

Once the project has been created, we are welcomed by the welcome and license page of the framework, the Readme file and the tabs with the CFrameWindow.h and CFrameWindow files already open.cpp.

Image 3

Note: The project based on the Win32Framework Ribbon framework is already ready to be compiled with the standard C++ 17 language. If your project is not, go to Properties -> General -> C++ Language Standard and be sure to choose version 17 [ISO C++17 Standard (/std:c++17)].

Image 4

We build the application to verify that everything is OK, or we run a Debug session of the Win32 app (see images above).

If your C++ Win32 starter app, compiled with the standard C++ version 17 is also OK, let's move on to the second step: the custom Runtime Component that will be consumed by our application.

Note: In order for a Runtime Component to be "consumed" by other applications, the class must be a runtime class. If we wanted to use the runtime component in a local application, that is, exclusively in the same project, an ordinary C++ class would suffice.

We add a new project and choose the template: Windows Runtime Component C++/WinRT. The WinRT component in this example will handle a queue delete system for which we give a meaningful name to the UWP project: TicketMachine.

We choose the minimum and maximum target of the operating system and confirm.

As already mentioned (see part 1), the Visual Studio wizard, in addition to everything you need to compile and instantiate the component correctly at runtime, has created for us a runtime class named Class and the IDL Class.idl file: More precisely, we find three files:

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

Image 5

The .idl file defines the C++/WinRT (Runtime Classes) classes. By opening the .idl (Interface Definition Language) file, which will be fed to the MICROSOFT Interface Definition Language (MIDL) tool during the compilation of the project, you can see the new IDL language syntax in its version 3.0.

For those who do not know COM (Component Object Model), remember that .idl files are used to describe COM types and interfaces. Those who know COM and therefore "traditional" IDL will find the syntax somewhat different because, in the updated version, the language has been simplified and modified to support the types of Windows Runtime.

In the solution in Visual Studio, we select the UWP project TicketMachine; first we rename the file Class.idl. We choose a meaningful name.

Note: C++/WinRT creates a corresponding .winmd file for each .idl file, so to avoid having multiple .winmd files, I will declare all interfaces and classes in a single .idl file. This technique is perfectly legal and allows, in complex projects, to greatly shorten build times.

In our example, interfaces and classes will be collected (see note above) in a single .idl file; I will call the latter Common.idl. Once the .idl file is renamed, the two files, header and implementation, (Class.h and Class.cpp respectively) are automatically renamed.

Image 6

Once the three files have been renamed, we must correct the includes and the name of the class that by default refer to Class.

Image 7

Image 8

We continue by compiling the TicketMachine project for the first time, thus creating the first version (although currently useless) of the TicketMachine.winmd and TicketMachine files.dll.

We will see later that at the appropriate time, the DLL will be loaded at runtime (or rather, the operating system will do it for us) and, through it, we will have access to the metadata contained in the .winmd file by our Win32 application; in fact, since it is not possible (at least currently) to import directly into a native Win32 application, the types contained in a .winmd file, this is (at the moment) the way to access metadata. If you thought you could get away with it by simply importing a .winmd file into a native Win32 project by adding a reference in Visual Studio, well, you would change your mind if you tried as Visual Studio would block your way with the warning below:

A Brief Analysis for the Sample C++/WinRT Component

Our sample project will allow us to see encapsulation, inheritance and polymorphism at work from the C++/WinRT point of view; we will design a WinRT component that manages queues at the counters of a hypothetical office and a Win32 Classic C++ client application that will "consume" the same.

Also in the component, we will also implement some events that can then be managed, as well as in the Win32 client, in applications (whether they are UWP, .NET, etc.) possibly implemented in the future.

First, we identify the entities involved: → Services → Branches → Operators → Totems for tickets → Tickects via smartphone app → Queue operations waiting → Log completed operations.

Some initial specifications:

  • → An operator, for each working day, can be assigned to any counter.
  • → Each operator at his counter can perform all services.
  • → For each ticket in the queue, you must indicate the estimated waiting time.
  • → A waiting start event must be raised when the ticket is issued.
  • → A close operation event must be raised when the operation is completed.

From the above, it can be deduced that the following interfaces and classes should be implemented:

  • Interfaces:
    • IServices Property
    • IDesks
    • IOperators
    • ITickets
  • Classes:
    • Service
    • Desk
    • Operator
    • Ticket
    • OperationsQueue
    • OperationsLog

We represent with a UML graph the relationships we intend to develop.

Image 9

We define interfaces and classes in the Common.idl file:

C++
////====================================================================
//                          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; };
    };
}

We build the TicketMachine project to allow Visual Studio to create all stubs files (h and cpp).

Image 10

Now we open the folder of the Project TicketMachine and create a new folder with the name of your choice, I will call it Generated. Within this, we copy all the files (h and cpp) that Visual Studio has created in the subfolder of the project .. \TicketMachine\Generated Files\sources except Common.h and Common.cpp.

So in Solution Explorer, in the Generated Files filter, we right-click -> Add -> Existing Item... and add all the files of the newly created folder (Generated in my case).

Image 11

Image 12

Image 13

Let's comment in all the files of the Generated folder (h and cpp) the line:

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

Compile the TicketMachine project and make sure TicketMachine.winmd and TicketMachine.dll were produced by Visual Studio.

Image 14

Soon, we will see how to consume our WinRT component in a native Win32 application, but first let's take care of implementing, in the respective classes, properties, methods and events.

We will implement the Date, Service, Operator, Desk, and Ticket classes first. The Date class aims to implement two new data types (Date and Time); Service, Operator and Ticket will provide a static list, respectively, of services, operators and branches; obviously in a real application, this data would come from a database or a webservice. The Ticket class will be used to (precisely) create the tickets of the reservations at the counters.

Date.h

C++
////====================================================================
//                          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>
    {
    };
}
C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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;
    }
}

The Create method in the Ticket.cpp file must be called, by the applications that consume the component, whenever a new ticket needs to be created.

This, after being created, will queue to any other pending tickets, for the purpose we will implement the OperationsQueue class.

Each ticket, once the operation at the counter is completed, will be inserted in another area (in a real application in a database, etc.) that we will represent here with the OperationsLog class.

If we analyze the Create method, we can see that the Collection class is instantiated several times.

The purpose of this template class is to create a list of:

  • services
  • doors
  • operators

and associate them with each other (if we want) in a pseudo-random way. Therefore, every time we perform the Create method, we will have a different combination of services, counters and operators.

This mechanism, at runtime, will simulate the function of a Totem for the issuance of tickets. The Collection template class is located in the Helpers.h include file:

Helpers.h

C++
////====================================================================
//                          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;
	}
};

Events in a C++/WinRT Component

As we well know, in general, an event in a class is the way to notify the application that uses that class that "something" has just happened (e.g.: click on a button, end of downloading a file, etc.). In C++/WinRT, an event is declared as a delegate type and must be logged in order to be managed; finally when no longer used, it can be revoked.

Depending on the case, an event can be declared as a delegate type among the following:

  • winrt::d bound
  • winrt::event

We will use the type winrt::d ebound when the event does not have to communicate "with the outside"; instead we will use winrt::event when the event must be accessible through ABI (application binary interface), that is, when both the WinRT component, and the application that consumes it, access the event.

Equally notorious is that an event can have arguments.

In the case of the winrt::d elegated type, it is not strictly necessary that the argument be a Windows Runtime type, but it can be of type Windows Runtime or custom type. Conversely, for the winrt::event type, the argument can only be of type Windows Runtime or primitive type (int, float, etc.). Now, since the events of our TicketMachine component must "pass" ABI, we declare in the Common.idl file in the Operations queue class two events of type: winr::event, both with argument of type bool.

The first event will be invoked when a new ticket is issued and the second when an operation has been completed.

Common.idl

C++
.............................
.............................
.............................

//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;

Following the declaration and implementation of the classes:

  • OperationsQueue
  • OperationsLog
  • StartQueueEventArgs
  • CloseOperationEventArgs Property

OperationsQueue.h

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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

C++
////====================================================================
//                          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;
    }
}

The component is ready, we compile the project and produce an updated version of TicketMachine.dll and TicketMachine.winmd.

In the next, as well as the last part of this tutorial, we will see how to consume the C++/WinRT component in a Win32 C++ application.

Go to Part 4. Implementing the demo C++ Win32 Application

History

  • 14th January, 2022: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Giuseppe Pischedda
Software Developer (Senior)
Italy Italy
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pin
Ștefan-Mihai MOGA14-Jan-22 21:49
professionalȘtefan-Mihai MOGA14-Jan-22 21:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.