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.

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, Windows Runtime C++ Template Library 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 Windows Runtime C++ Template Library in a Universal Windows Platform (UWP) app, this example uses a console app for illustration. Functions such as wprintf_s are not available from a UWP app. For more information about the types and functions that you can use in a UWP app, see CRT functions not supported in Universal Windows Platform apps and Win32 and COM for UWP apps.

To activate and use a Windows Runtime component

  1. Include (#include) any required Windows Runtime, Windows Runtime C++ Template Library, or C++ Standard 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.

  2. 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 calls Windows::Foundation::Initialize at construction, and Windows::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 to Windows::Foundation::Initialize.

  3. 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.

  4. 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"http://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.

  5. Use the IUriRuntimeClassFactory::CreateUri factory method to create a ABI::Windows::Foundation::IUriRuntimeClass object.

    // Create the IUriRuntimeClass object.
    ComPtr<IUriRuntimeClass> uri;
    hr = uriFactory->CreateUri(uriHString.Get(), &uri);
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }
    
  6. Call the IUriRuntimeClass::get_Domain method to retrieve the value of the Domain property.

    // Get the domain part of the URI.
    HString domainName;
    hr = uri->get_Domain(domainName.GetAddressOf());
    if (FAILED(hr))
    {
        return PrintError(__LINE__, hr);
    }
    
  7. 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"http://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

See also

Windows Runtime C++ Template Library (WRL)