A Simple Windows Runtime Component using WRL and C++ with an event/delegate.


COM, C++, WRL, IDL
WRL Basic component, WRL dllmain
Desktop, Windows RT
en-US
2/1/2016

Introduction

The project template named "WRL Class Library" is no longer available by Microsoft. So to develop an simple Windows Runtime components, you will go directly to C++/CX. With my sample, you can use directly the C++ ISO (you love it) and makes a component.

Building the Sample

The projects can be used with Visual Studio 2013 or 2015. Any IDE that can build WIndows 8.1 apps.

Description

To create a WinRT component, you need to provide an IDL file. yes, this is traditionnal COM programming. Look:

 

C++
Modifier le script|Remove
// Library3.IDL 
import "inspectable.idl"; 
import "Windows.Foundation.idl"; 
 
#define COMPONENT_VERSION 1.0 
 
namespace Library3 
{ 
    interface IGame; 
    runtimeclass Game; 
 
    [uuid(1FCD374B-2C3C-49E3-93A7-6FB801080D45), version(COMPONENT_VERSION)] 
    delegate HRESULT GameEventHandler([in] HSTRING e); 
 
    [uuid(3EC4B4D6-14A6-4D0D-BB96-31DA25224A15), version(COMPONENT_VERSION)] 
    interface IGame : IInspectable 
    { 
        [propget] HRESULT RegisterUser([out, retval] HSTRING* value); 
        [propput] HRESULT RegisterUser([in] HSTRING value); 
        HRESULT StartGame([in] HSTRING value); 
        [eventadd] HRESULT UserLogged([in] GameEventHandler* handler, [out][retval] EventRegistrationToken* token); 
        [eventremove] HRESULT UserLogged([in] EventRegistrationToken token); 
    } 
 
    [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)] 
    runtimeclass Game 
    { 
        [default] interface IGame; 
    } 
 
    declare 
    { 
        interface Windows.Foundation.IAsyncOperation<IGame*>; 
    } 
} 

Source Code Files

More Information

You can use my sample as the beginning to create your own WRL component. The first step is to create the IDL file. My IDL file is based on what was present in the WRL Project Template. You can see the glue to make this DLL a new COM component registred and usable with the Windows Runtime in the module.cpp file.


// module.cpp : Defines the module that contains the com classes

//

 

#include "pch.h"

   

#include <wrl\module.h>

  

extern "C" BOOL WINAPI DllMain(_In_opt_ HINSTANCE, DWORD, _In_opt_ LPVOID);

extern "C" HRESULT WINAPI DllCanUnloadNow();

#if !defined(__WRL_CLASSIC_COM__)

extern "C" HRESULT WINAPI DllGetActivationFactory(_In_ HSTRING, _Deref_out_ IActivationFactory**);

extern "C" HRESULT WINAPI DllGetActivationFactory(_In_ HSTRING activatibleClassId, _Deref_out_ IActivationFactory** factory)

{

auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();

return module.GetActivationFactory(activatibleClassId, factory);

}

#endif

#if !defined(__WRL_WINRT_STRICT__)

extern "C" HRESULT WINAPI DllGetClassObject(REFCLSID, REFIID, _Deref_out_ LPVOID*);

extern "C" HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, _Deref_out_ LPVOID *ppv)

{

auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();

return module.GetClassObject(rclsid, riid, ppv);

}

#endif

extern "C" BOOL WINAPI DllMain(_In_opt_ HINSTANCE, DWORD, _In_opt_ LPVOID)

{

return TRUE;

}

extern "C" HRESULT WINAPI DllCanUnloadNow()

{

const auto &module = Microsoft::WRL::Module<Microsoft::WRL::InProc>::GetModule();

return module.GetObjectCount() == 0 ? S_OK : S_FALSE;

}

#if defined(_M_IX86)

#if !defined(__WRL_CLASSIC_COM__)

#pragma comment(linker, "/EXPORT:DllGetActivationFactory=_DllGetActivationFactory@8,PRIVATE")

#endif

#if !defined(__WRL_WINRT_STRICT__)

#pragma comment(linker, "/EXPORT:DllGetClassObject=_DllGetClassObject@12,PRIVATE")

#endif

#pragma comment(linker, "/EXPORT:DllCanUnloadNow=_DllCanUnloadNow@0,PRIVATE")

#elif defined(_M_ARM) || defined(_M_AMD64)

#if !defined(__WRL_CLASSIC_COM__)

#pragma comment(linker, "/EXPORT:DllGetActivationFactory,PRIVATE")

#endif

#if !defined(__WRL_WINRT_STRICT__)

#pragma comment(linker, "/EXPORT:DllGetClassObject,PRIVATE")

#endif

#pragma comment(linker, "/EXPORT:DllCanUnloadNow,PRIVATE")

#endif