How to: Activate and Use a 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 How to: Activate and Use a Windows Runtime Component Using WRL.
This document shows how to use the Windows Runtime C++ Template Library (WRL) to initialize the Windows Runtime and how to activate and use a Windows Runtime component.
Note
This example activates a built-in Windows Runtime component. To learn how to create your own component that you can activate in a similar manner, see Walkthrough: Creating a Basic Windows Runtime Component.
To use a component, you must acquire an interface pointer to the type that is implemented by the component. And because the underlying technology of the Windows Runtime is the Component Object Model (COM), you must follow COM rules to maintain an instance of the type. For example, you must maintain the reference count that determines when the type is deleted from memory.
To simplify the use of the Windows Runtime, WRL provides the smart pointer template, ComPtr<T>, that automatically performs reference counting. When you declare a variable, specify ComPtr<
interface-name>
identifier. To access an interface member, apply the arrow member-access operator (->
) to the identifier.
Important
When you call an interface function, always test the HRESULT
return value.
Activating and Using a Windows Runtime Component
The following steps use the Windows::Foundation::IUriRuntimeClass
interface to demonstrate how to create an activation factory for a Windows Runtime component, create an instance of that component, and retrieve a property value. They also show how to initialize the Windows Runtime. The complete example follows.
Important
Although you typically use the WRL in a Windows 8.x Store app, this example uses a console app for illustration. Functions such as wprintf_s
are not available from a Windows 8.x Store app. For more information about the types and functions that you can use in a Windows 8.x Store app, see CRT functions not supported with /ZW and Win32 and COM for Windows Store apps.
To activate and use a Windows Runtime component
Include (
#include
) any required Windows Runtime, WRL, or standard C++ library headers.#include <Windows.Foundation.h> #include <wrl\wrappers\corewrappers.h> #include <wrl\client.h> #include <stdio.h> using namespace ABI::Windows::Foundation; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers;
We recommend that you utilize the
using namespace
directive in your .cpp file to make the code more readable.Initialize the thread in which the app executes. Every app must initialize its thread and threading model. This example uses the Microsoft::WRL::Wrappers::RoInitializeWrapper class to initialize the Windows Runtime and specifies RO_INIT_MULTITHREADED as the threading model. The
RoInitializeWrapper
class callsWindows::Foundation::Initialize
at construction, andWindows::Foundation::Uninitialize
when it is destroyed.// Initialize the Windows Runtime. RoInitializeWrapper initialize(RO_INIT_MULTITHREADED); if (FAILED(initialize)) { return PrintError(__LINE__, initialize); }
In the second statement, the RoInitializeWrapper::HRESULT operator returns the
HRESULT
from the call toWindows::Foundation::Initialize
.Create an activation factory for the
ABI::Windows::Foundation::IUriRuntimeClassFactory
interface.// Get the activation factory for the IUriRuntimeClass interface. ComPtr<IUriRuntimeClassFactory> uriFactory; HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
The Windows Runtime uses fully-qualified names to identify types. The
RuntimeClass_Windows_Foundation_Uri
parameter is a string that's provided by the Windows Runtime and contains the required runtime class name.Initialize a Microsoft::WRL::Wrappers::HString variable that represents the URI
"https://www.microsoft.com"
.// Create a string that represents a URI. HString uriHString; hr = uriHString.Set(L"https://www.microsoft.com"); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
In the Windows Runtime, you don’t allocate memory for a string that the Windows Runtime will use. Instead, the Windows Runtime creates a copy of your string in a buffer that it maintains and uses for operations, and then returns a handle to the buffer that it created.
Use the
IUriRuntimeClassFactory::CreateUri
factory method to create aABI::Windows::Foundation::IUriRuntimeClass
object.// Create the IUriRuntimeClass object. ComPtr<IUriRuntimeClass> uri; hr = uriFactory->CreateUri(uriHString.Get(), &uri); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
Call the
IUriRuntimeClass::get_Domain
method to retrieve the value of theDomain
property.// Get the domain part of the URI. HString domainName; hr = uri->get_Domain(domainName.GetAddressOf()); if (FAILED(hr)) { return PrintError(__LINE__, hr); }
Print the domain name to the console and return. All
ComPtr
and RAII objects leave scope and are released automatically.// Print the domain name and return. wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr)); // All smart pointers and RAII objects go out of scope here.
The WindowsGetStringRawBuffer function retrieves the underlying Unicode form of the URI string.
Here's the complete example:
// wrl-consume-component.cpp
// compile with: runtimeobject.lib
#include <Windows.Foundation.h>
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
#include <stdio.h>
using namespace ABI::Windows::Foundation;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
// Prints an error string for the provided source code line and HRESULT
// value and returns the HRESULT value as an int.
int PrintError(unsigned int line, HRESULT hr)
{
wprintf_s(L"ERROR: Line:%d HRESULT: 0x%X\n", line, hr);
return hr;
}
int wmain()
{
// Initialize the Windows Runtime.
RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
{
return PrintError(__LINE__, initialize);
}
// Get the activation factory for the IUriRuntimeClass interface.
ComPtr<IUriRuntimeClassFactory> uriFactory;
HRESULT hr = GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_Uri).Get(), &uriFactory);
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Create a string that represents a URI.
HString uriHString;
hr = uriHString.Set(L"https://www.microsoft.com");
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Create the IUriRuntimeClass object.
ComPtr<IUriRuntimeClass> uri;
hr = uriFactory->CreateUri(uriHString.Get(), &uri);
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Get the domain part of the URI.
HString domainName;
hr = uri->get_Domain(domainName.GetAddressOf());
if (FAILED(hr))
{
return PrintError(__LINE__, hr);
}
// Print the domain name and return.
wprintf_s(L"Domain name: %s\n", domainName.GetRawBuffer(nullptr));
// All smart pointers and RAII objects go out of scope here.
}
/*
Output:
Domain name: microsoft.com
*/
Compiling the Code
To compile the code, copy it and then paste it in a Visual Studio project, or paste it in a file that is named wrl-consume-component.cpp
and then run the following command in a Visual Studio Command Prompt window.
cl.exe wrl-consume-component.cpp runtimeobject.lib