August 2013

Volume 28 Number 8

Windows with C++ - The Windows Runtime Application Model

By Kenny Kerr | August 2013

Kenny KerrOur lives are replete with abstractions. As developers, we’re often left struggling when we use abstractions without understanding them for what they are. Abstractions are sometimes broken and fail to completely hide underlying complexity. Don’t get me wrong, abstractions are great. They help users and they help developers, but you’ll do yourself a world of good if you dig into the abstractions that you rely on regularly to understand how they operate. Moreover, libraries that acknowledge this reality are often more successful than ones that don’t, in part because they allow you to step around the abstraction if and when you feel the need.

The Windows Runtime (WinRT) is one such abstraction, and in this month’s column I’m going to illustrate this by examining the WinRT core application model. It revolves around the CoreWindow class, of which there’s an instance that lives inside each and every “modern” Windows Store and Windows Phone app. Yet relatively few developers even know it exists, let alone how it works. Perhaps this is a testament to the success of the abstraction.

Since the Windows 8 API was first announced in 2011, a lot has been spoken and written about the various language projections that offer an abstraction over the Windows Runtime. However, the best way to understand the Windows Runtime is to eschew the various language projections, including C++/CX, and embrace standard C++ and classic COM. Only C++ lets you pull the curtain aside and see what’s really going on (technically, so does C, but that would be needlessly painful). You might still choose to use some or other language projection (hopefully C++/CX), as you probably should, but at least you’ll have a much clearer understanding of what’s really going on.

To begin, open Visual Studio 2012 and create a new Visual C++ project for a Windows Store or Windows Phone app. It doesn’t matter which template you use. Once it’s loaded, go over to the Solution Explorer and delete everything that’s nonessential. If you picked a XAML-based template, delete all of the XAML files. You can also delete all of the C++ sources files. You might want to hold on to the precompiled header, but be sure to delete everything inside of it. All that should remain are the package assets required to deploy the app, images, certificate and XML manifest.

Next, open the project’s property pages and select the compiler properties—the C/C++ node in the tree on the left. Find the line for the /ZW compiler option that’s called Consume Windows Runtime Extension and select No to disable the C++/CX language extensions. That way you can be sure there’s nothing mysterious going on beyond the wonderful mysteries of the standard C++ compiler. While you’re there, you might as well set the compiler’s warning level to /W4.

If you try to compile the project, you should be greeted with a linker error informing you that the project’s WinMain entry point function can’t be found. Add a new C++ source file to the project, and the first thing you’ll do is add the missing WinMain function:

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int)
{
}

As you can see, this is the age-old WinMain function for a C Runtime Libraries (CRT)-based Windows application. Of course, HINSTANCE and PWSTR aren’t fundamental C++ types, so you’ll need to include the Windows header:

#include <windows.h>

If you kept the project’s precompiled header, you can include it in there. I’ll also be using ComPtr from the Windows Runtime C++ Template Library (WRL), so now would be a good time to include that as well:

#include <wrl.h>

I’ll cover WRL in more detail over the next few columns. For now, I’ll just make use of the ComPtr class template for maintaining a COM interface pointer. All you need to keep in mind at this stage is that the WRL ComPtr is simply a COM interface smart pointer. Although it provides certain features that are unique to the Windows Runtime, I won’t be using them in this month’s column. You could just as easily use the Active Template Library (ATL) CComPtr instead, or any COM interface smart pointer of your choice. The WRL ComPtr is defined in the Microsoft::WRL namespace:

using namespace Microsoft::WRL;

I’m also going to use an ASSERT macro as well as the HR function for error handling. I’ve discussed these previously, so I won’t go over them again here. If you’re unsure about these steps, check out my May 2013 column, “Introducing Direct2D 1.1” (msdn.microsoft.com/magazine/dn198239).

Finally, to use any of the WinRT functions mentioned in this column, you need to give the linker the name of the .lib file:

#pragma comment(lib, "RuntimeObject.lib")

The first thing the application model expects is a multithreaded apartment (MTA). That’s right—the COM apartment model lives on. The Windows Runtime provides the RoInitialize function, which is a thin wrapper around CoInitializeEx:

HR(RoInitialize(RO_INIT_MULTITHREADED));

Despite the fact that CoInitializeEx is usually sufficient, I suggest you use RoInitialize. This function allows future improvements to be made to the Windows Runtime without potentially breaking classic COM. It’s analogous to OleInitialize, which also calls CoInitializeEx and then some. The point is that there’s nothing mysterious about your application’s main thread. The only thing that might be slightly surprising is that it’s not a single-threaded apartment (STA). Don’t worry, your application’s window will still run from within an STA thread, but the Windows Runtime will be the one creating it. This STA is actually an Application STA (ASTA), which is slightly different, but more on that later.

 The next bit is a little tricky. The Windows Runtime forsakes the traditional COM activation model that uses GUID-based class identifiers in favor of a model that activates classes based on textual class identifiers. The textual names are based on namespace-scoped class names popularized by Java and the Microsoft .NET Framework, but before you scoff and say good riddance to the registry, keep in mind that these new class identifiers are still stored in the registry. Technically only first-party types are registered in the registry, whereas third-party types are only registered in a per-application manifest. There are pros and cons to this change. One of the cons is that it’s slightly harder to describe the class identifier when calling a WinRT function. The Windows Runtime defines a new remotable string type to replace the traditional BSTR string type, and any class identifiers need to be provided using this new medium. The HSTRING, as it’s called, is far less error-prone than BSTR, chiefly because it’s immutable. The simplest way to create an HSTRING is with the WindowsCreateString function:

wchar_t buffer[] = L"Poultry.Hatchery";
HSTRING string;
HR(WindowsCreateString(buffer,
                       _countof(buffer) - 1,
                       &string));

WindowsCreateString allocates enough memory to store a copy of the source string as well as a terminating null character and then copies the source string into this buffer. To release the backing buffer you must remember to call WindowsDeleteString, unless ownership of the string is returned to a calling function:

HR(WindowsDeleteString(string));

Given an HSTRING, you can get a pointer to its backing buffer with the WindowsGetStringRawBuffer function:

wchar_t const * raw = WindowsGetStringRawBuffer(string, nullptr);

The optional second parameter returns the length of the string. The length is stored with the string, saving you from having to scan the string to determine its length. Before you run off and write a C++ wrapper class, it’s worth noting that the C++/CX compiler doesn’t bother with WindowsCreateString and WindowsDelete­String when generating code for a string literal or const array. Instead, it uses what’s known as a fast-pass string that avoids the extra memory allocation and copy that I previously mentioned. This also avoids the risk of a memory leak. The WindowsCreate­StringReference function creates a fast-pass string:

HSTRING_HEADER header;
HSTRING string;
HR(WindowsCreateStringReference(buffer,
                                _countof(buffer) - 1,
                                &header,
                                &string));

This function uses the caller-provided HSTRING_HEADER to avoid a heap allocation. In this case, the backing buffer for the HSTRING is the source string itself, so you must ensure that the source string (as well as the header) remains unchanged for the life of the HSTRING. This approach obviously isn’t of any use when you need to return a string to a calling function, but it’s a worthy optimization when you need to pass a string as an input to another function whose lifetime is scoped by the stack (not asynchronous functions). WRL also provides wrappers for HSTRING and fast-pass strings.

RoGetActivationFactory is just such a function and is used to get the activation factory or static interface for a given class. This is analogous to the COM CoGetClassObject function. Given that this function is usually used with a const array generated by the MIDL compiler, it makes sense to write a simple function template to provide a fast-pass string wrapper. Figure 1 illustrates what this might look like.

Figure 1 GetActivationFactory Function Template

template <typename T, unsigned Count>
auto GetActivationFactory(WCHAR const (&classId)[Count]) -> ComPtr<T>
{
  HSTRING_HEADER header;
  HSTRING string;
  HR(WindowsCreateStringReference(classId,
                                  Count - 1,
                                  &header,
                                  &string));
  ComPtr<T> result;
  HR(RoGetActivationFactory(string,
    __uuidof(T),
    reinterpret_cast<void **>(result.GetAddressOf())));
  return result;
}

The GetActivationFactory function template infers the string length automatically, eliminating an error-prone buffer length argument or costly runtime scan. It then prepares a fast-pass string before calling the actual RoGetActivationFactory function. Here, again, the function template infers the interface identifier and safely returns the resulting COM interface pointer wrapped in a WRL ComPtr.

You can now use this helper function to get the ICoreApplication interface:

using namespace ABI::Windows::ApplicationModel::Core;
auto app = GetActivationFactory<ICoreApplication>(
  RuntimeClass_Windows_ApplicationModel_Core_CoreApplication);

The ICoreApplication interface is what gets the ball rolling for your application. To use this COM interface, you’ll need to include the application model header:

#include <Windows.ApplicationModel.Core.h>

This header defines ICoreApplication, inside the ABI::Windows::ApplicationModel::Core namespace, as well as the Core­Application’s textual class identifier. The only interface method you really need to think about is the Run method.

Before I go on, it’s helpful to appreciate how the Windows Runtime brings your application to life. As I’ve mentioned before, the Windows Runtime considers you only a guest inside your own process. This is analogous to how Windows services have worked for years. In the case of a Windows service, the Windows Service Control Manager (SCM) starts the service using the CreateProcess function, or one of its variants. It then waits for the process to call the StartServiceCtrlDispatcher function. This function establishes a connection back to the SCM whereby the service and the SCM can communicate. If, for example, the service fails to call StartService­CtrlDispatcher in a timely fashion, the SCM will assume something went wrong and tear down the process. The StartServiceCtrl­Dispatcher function only returns when the service has ended, so the SCM needs to create a secondary thread for the service to receive callback notifications. The service merely responds to events and is at the mercy of the SCM. As you’ll discover, this is remarkably similar to the WinRT application model.

The Windows Runtime waits for the process to get the ICore­Application interface and call its Run method. Like the SCM, if the process fails to do so in a timely manner, the Windows Runtime assumes that something went wrong and tears down the process. Thankfully, if a debugger is attached, the Windows Runtime notices and disables the timeout, unlike the SCM. However, the model is the same. The Windows Runtime is in charge and calls the application on a runtime-created thread when events occur. Of course, the Windows Runtime is COM-based, so instead of a callback function (as is the case with the SCM) the Windows Runtime—which relies on the Process Lifetime Manager (PLM) for this—expects the application to provide the Run method with a COM interface that it can use to call the application.

Your app must provide an implementation of IFramework­ViewSource, which also hails from the ABI::Windows::ApplicationModel::Core namespace, and CoreApplication will call its solitary CreateView method once it has created your app’s UI thread. IFrameworkViewSource doesn’t really just have CreateView as a method. It derives from IInspectable, the WinRT base interface. IInspectable in turn derives from IUnknown, the COM base interface.

WRL provides extensive support for implementing COM classes, but I’ll save that for an upcoming column. For now, I want to underline how the Windows Runtime really is rooted in COM, and what better way to show that than by implementing IUnknown? For my purposes, it’s useful to note that the C++ class that will implement IFrameworkViewSource—and a few others—has its lifetime defined by the stack. Essentially, the application’s WinMain function boils down to this:

HR(RoInitialize(RO_INIT_MULTITHREADED));
auto app = GetActivationFactory<ICoreApplication>( ...
SampleWindow window;
HR(app->Run(&window));

All that remains is to write the SampleWindow class so that it properly implements IFrameworkViewSource. Although CoreApplication doesn’t care where they’re implemented, at a minimum your app will need to implement not only IFrameworkViewSource but also the IFrameworkView and IActivatedEventHandler interfaces. In this case, the SampleWindow class can just implement them all:

struct SampleWindow :
  IFrameworkViewSource,
  IFrameworkView,
  IActivatedEventHandler
{};

The IFrameworkView interface is also defined in the ABI::Windows::ApplicationModel::Core namespace, but IActivatedEvent­Handler is a little harder to pin down. I’ve defined it myself as follows:

using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::ApplicationModel::Activation;
typedef ITypedEventHandler<CoreApplicationView *, 
  IActivatedEventArgs *>
  IActivatedEventHandler;

If you have some experience with COM, you might think this looks rather unorthodox—and you’d be right. As you’d expect, ITypedEventHandler is just a class template, and that’s a rather odd way to define a COM interface—the most obvious problem being that you couldn’t possibly know what interface identifier to attribute it with. Fortunately, all of these interfaces are generated by the MIDL compiler, which takes care to specialize each one, and it’s on these specializations that it attaches the GUID representing the interface identifier. As complicated as the previous typedef might appear, it defines a COM interface that derives directly from IUnknown and provides a single method called Invoke.

I have a few interface methods to implement, so let’s get started. First up is IUnknown and the mighty QueryInterface method. I don’t want to spend too much time on IUnknown and IInspectable here, as I’ll be covering them in detail in an upcoming column. Figure 2 provides a simple implementation of QueryInterface for a stack-based class such as this.

Figure 2 The SampleWindow QueryInterface Method

auto __stdcall QueryInterface(IID const & id,
                              void ** result) -> HRESULT
{
  ASSERT(result);
  if (id == __uuidof(IFrameworkViewSource) ||
      id == __uuidof(IInspectable) ||
      id == __uuidof(IUnknown))
  {
    *result = static_cast<IFrameworkViewSource *>(this);
  }
  else if (id == __uuidof(IFrameworkView))
  {
    *result = static_cast<IFrameworkView *>(this);
  }
  else if (id == __uuidof(IActivatedEventHandler))
  {
    *result = static_cast<IActivatedEventHandler *>(this);
  }
  else
  {
    *result = nullptr;
    return E_NOINTERFACE;
  }
  // static_cast<IUnknown *>(*result)->AddRef();
  return S_OK;
}

A few things are worth noting about this implementation. First, the method asserts that its arguments are valid. A more politically correct implementation might return E_POINTER, but it’s assumed that such errors are bugs that can be resolved during development, so there’s no need to waste extra cycles at run time. This gives the best possible behavior by immediately causing an access violation and a crash dump that’s pretty easy to analyze. If you return E_POINTER, the broken caller will probably just ignore it. The best policy is to fail early. This is in fact the position taken by many implementations, including DirectX and the Windows Runtime. A lot goes into implementing QueryInterface correctly. The COM specification is quite specific so that COM classes will always provide certain object identity guarantees correctly and consistently. Don’t worry if the chain of if statements looks intimidating. I’ll cover it in due course.

The final point worth mentioning about this implementation is that it doesn’t bother to call AddRef. Ordinarily, QueryInterface must call AddRef on the resulting IUnknown interface pointer before returning. However, because the SampleWindow class resides on the stack, there’s no point in reference counting. For the same reason, implementing the IUnknown AddRef and Release methods is straightforward:

auto __stdcall AddRef()  -> ULONG { return 2; }
auto __stdcall Release() -> ULONG { return 1; }

The results of these methods are only advisory, so you can take advantage of this fact, and any non-zero value will do. A word of caution here: You might want to override operators new and delete to make it explicit that the class is only designed to work on the stack. Alternatively, you could simply implement reference counting, just in case.

Next, I need to implement IInspectable, but because it won’t be used for this simple application, I’ll cheat and leave its methods not implemented, as shown in Figure 3. This isn’t a conforming implementation and isn’t guaranteed to work. Again, I’ll cover IInspectable in an upcoming column, but this is sufficient to get the SampleWindow IInspectable-derived interfaces up and running.

Figure 3 The SampleWindow IInspectable Methods

auto __stdcall GetIids(ULONG *,
                       IID **) -> HRESULT
{
  return E_NOTIMPL;
}
auto __stdcall GetRuntimeClassName(HSTRING *) -> HRESULT
{
  return E_NOTIMPL;
}
auto __stdcall GetTrustLevel(TrustLevel *) -> HRESULT
{
  return E_NOTIMPL;
}

Next, I need to implement IFrameworkViewSource and its CreateView method. Because the SampleWindow class is also implementing IFrameworkView, the implementation is simple. Again, note that ordinarily you’d need to call AddRef on the resulting IUnknown-derived interface pointer before returning. You might want to call AddRef in the body of this function, just in case:

auto __stdcall CreateView(IFrameworkView ** result) -> HRESULT
{
  ASSERT(result);
  *result = this;
  // (*result)->AddRef();
  return S_OK;
}

The IFrameworkView interface is where things finally get interesting for the application. After calling CreateView to retrieve the interface pointer from the application, the Windows Runtime calls most of its methods in quick succession. It’s important that you respond to these calls quickly, as they all count as time spent by the user waiting for your application to start. The first is called Initialize, and this is where the application must register for the Activated event. The Activated event signals that the application has been activated, but it’s up to the application to activate its CoreWindow. The Initialize method is quite simple:

auto __stdcall Initialize(ICoreApplicationView * view) -> HRESULT
{
  EventRegistrationToken token;
  HR(view->add_Activated(this, &token));
  return S_OK;
}

The SetWindow method is then called, providing the application with the actual ICoreWindow implementation. An ICoreWindow just models a regular desktop HWND inside the Windows Runtime. Unlike the previous application model interfaces, ICoreWindow is defined in the ABI::Windows::UI::Core namespace. Inside the SetWindow method you should just make a copy of the interface pointer, as you’ll need it soon enough:

using namespace ABI::Windows::UI::Core;
ComPtr<ICoreWindow> m_window;
auto __stdcall SetWindow(ICoreWindow * window) -> HRESULT
{
  m_window = window;
  return S_OK;
}

The Load method is next and is where you should stick any and all code to prepare your application for initial presentation:

auto __stdcall Load(HSTRING) -> HRESULT
{
  return S_OK;
}

At a minimum, you should register for events related to window size and visibility changes, as well as changes to DPI scaling. You might also take the opportunity to create the various DirectX factory objects, load device-independent resources and so on. The reason this is a good spot for all of this is that it’s at this point that the user is presented with your application’s splash screen.

When the Load method returns, the Windows Runtime assumes your application is ready to be activated and fires the Activated event, which I’ll handle by implementing the IActivatedEventHandler Invoke method, like so:

auto __stdcall Invoke(ICoreApplicationView *,
                      IActivatedEventArgs *) -> HRESULT
{
  HR(m_window->Activate());
  return S_OK;
}

With the window activated, the application is finally ready to run:

auto __stdcall Run() -> HRESULT
{
  ComPtr<ICoreDispatcher> dispatcher;
  HR(m_window->get_Dispatcher(dispatcher.GetAddressOf()));
  HR(dispatcher->ProcessEvents(CoreProcessEventsOption_ProcessUntilQuit));
  return S_OK;
}

There are many ways to implement this. Here I’m just retrieving the window’s ICoreDispatcher interface, which represents the message pump for the window. Finally, there’s the Uninitialize method, which might be called occasionally but is otherwise useless and can safely be ignored:

auto __stdcall Uninitialize() -> HRESULT
{
  return S_OK;
}

And that’s it. You can now compile and run the application. Of course, you’re not actually painting anything here. You can grab a copy of dx.h from dx.codeplex.com and start adding some Direct2D rendering code (see my June 2013 column, “A Modern Library for DirectX Programming,” at msdn.microsoft.com/magazine/dn201741 for more about that), or wait till my next column, where I’ll show you how best to integrate Direct2D with the WinRT core application model.


Kenny Kerr is a computer programmer based in Canada, an author for Pluralsight and a Microsoft MVP. He blogs at kennykerr.ca and you can follow him on Twitter at twitter.com/kennykerr.

Thanks to the following technical expert for reviewing this article: James McNellis (Microsoft)
James McNellis is a C++ aficionado and a software developer on the Visual C++ team at Microsoft, where he where he builds C++ libraries and maintains the C Runtime libraries (CRT).  He tweets at @JamesMcNellis.