Walkthrough: Creating a Basic Windows Runtime Component Using WRL
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at Walkthrough: Creating a Basic Windows Runtime Component Using WRL.
This document shows how to use the Windows Runtime C++ Template Library (WRL) to create a basic Windows Runtime component. The component adds two numbers and raises an event when the result is prime. This document also demonstrates how to use the component from a Windows 8.x Store app that uses JavaScript.
Prerequisites
Experience with the Windows Runtime.
Experience with COM.
To create a basic Windows Runtime component that adds two numbers
In Visual Studio, create a Visual C++
WRLClassLibrary
project. The document Class Library Project Template describes how to download this template. Name the projectContoso
.In Contoso.cpp and Contoso.idl, replace all instances of "WinRTClass" with "Calculator".
In Contoso.idl, add the
Add
method to theICalculator
interface.HRESULT Add([in] int a, [in] int b, [out, retval] int* value);
In Contoso.cpp, add the
Add
method to thepublic
section of theCalculator
class.HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value) { if (value == nullptr) { return E_POINTER; } *value = a + b; return S_OK; }
Important
Because you’re creating a COM component, remember to use the
__stdcall
calling convention.We recommend that you use
_Out_
and other source annotation language (SAL) annotations to describe how a function uses its parameters. SAL annotations also describe return values. SAL annotations work with the C/C++ Code Analysis tool to discover possible defects in C and C++ source code. Common coding errors that are reported by the tool include buffer overruns, uninitialized memory, null pointer dereferences, and memory and resource leaks.
To use the component from a Windows 8.x Store app that uses JavaScript
In Visual Studio, add a new JavaScript
Blank App
project to theContoso
solution. Name the projectCalculatorJS
.In the
CalculatorJS
project, add a reference to theContoso
project.In default.html, replace the
body
section with these UI elements:<div> <input id="a" /> <input id="b" /> <p id="result">Result:</p> <button onclick="Add()">Add</button> </div>
In default.js, implement the
OnClick
function.function Add() { "use strict"; var calculator = new Contoso.Calculator(); var a = document.getElementById("a"); var b = document.getElementById("b"); document.getElementById("result").innerHTML = "Result: " + calculator.add(a.value, b.value); }
Note
In JavaScript, the first letter of a method name is changed to lowercase to match the standard naming conventions.
To add an event that fires when a prime number is calculated
In Contoso.idl, before the declaration of
ICalculator
, define the delegate type,PrimeNumberEvent
, which provides anint
argument.[uuid(3FBED04F-EFA7-4D92-B04D-59BD8B1B055E), version(COMPONENT_VERSION)] delegate HRESULT PrimeNumberEvent(int primeNumber);
When you use the
delegate
keyword, the MIDL compiler creates an interface that contains anInvoke
method that matches that delegate's signature. In this example, the generated file Contoso_h.h defines theIPrimeNumberEvent
interface, which is used later in this procedure.MIDL_INTERFACE("3FBED04F-EFA7-4D92-B04D-59BD8B1B055E") IPrimeNumberEvent : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE Invoke( int primeNumber) = 0; };
In the
ICalculator
interface, define thePrimeNumberFound
event. Theeventadd
andeventremove
attributes specify that the consumer of theICalculator
interface can both subscribe to and unsubscribe from this event.[eventadd] HRESULT PrimeNumberFound( [in] PrimeNumberEvent* eventHandler, [out, retval] EventRegistrationToken* eventCookie); [eventremove] HRESULT PrimeNumberFound( [in] EventRegistrationToken eventCookie);
In Contoso.cpp, add a
private
Microsoft::WRL::EventSource member variable to manage the event subscribers and invoke the event handler.EventSource<IPrimeNumberEvent> m_events;
In Contoso.cpp, implement the
add_PrimeNumberFound
andremove_PrimeNumberFound
methods.HRESULT __stdcall add_PrimeNumberFound(_In_ IPrimeNumberEvent* event, _Out_ EventRegistrationToken* eventCookie) { return m_events.Add(event, eventCookie); } HRESULT __stdcall remove_PrimeNumberFound(_In_ EventRegistrationToken eventCookie) { return m_events.Remove(eventCookie); }
To raise the event when a prime number is calculated
In Contoso.cpp, add the
IsPrime
method to theprivate
section of theCalculator
class.// Determines whether the input value is prime. bool IsPrime(int n) { if (n < 2) { return false; } for (int i = 2; i < n; ++i) { if ((n % i) == 0) { return false; } } return true; }
Modify the
Calculator
’sAdd
method to call the Microsoft::WRL::EventSource::InvokeAll method when a prime number is calculated.HRESULT __stdcall Add(_In_ int a, _In_ int b, _Out_ int* value) { if (value == nullptr) { return E_POINTER; } int c = a + b; if (IsPrime(c)) { m_events.InvokeAll(c); } *value = c; return S_OK; }
To handle the event from JavaScript
In default.html, modify the
body
section to include a text area that contains prime numbers.<div> <input id="a" /> <input id="b" /> <p id="result">Result:</p> <p id="primes" style="color:#808080">Primes found:</p> <button onclick="Add()">Add</button> </div>
In default.js, modify the
Add
function to handle thePrimeNumberFound
event. The event handler appends the prime number to the text area that was defined by the previous step.function Add() { "use strict"; var calculator = new Contoso.Calculator(); calculator.onprimenumberfound = function (ev) { document.getElementById("primes").innerHTML += " " + ev.target; }; var a = document.getElementById("a"); var b = document.getElementById("b"); document.getElementById("result").innerHTML = "Result: " + calculator.add(a.value, b.value); }
Note
In JavaScript, the event names are changed to lower-case and are prepended with "on" to match the standard naming conventions.
The following illustration shows the basic Calculator app.
Next Steps
See Also
Windows Runtime C++ Template Library (WRL)
Class Library Project Template
C/C++ Code Analysis tool