Search code examples
xamluwpc++-winrt

Constructing Xaml controls on C++/WinRT UI thread


I'm not sure what I'm doing wrong, but even though I'm definitely on the UI thread, I'm consistently getting the error " 'The application called an interface that was marshalled for a different thread.'" when constructing Xaml controls in C++.

See the following basic example, which uses a stripped down version of the default C++/WinRT CoreApplication template:

#include "pch.h"

using namespace winrt;

using namespace Windows;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Composition;
using namespace Windows::ApplicationModel::Activation;

struct App : implements<App, IFrameworkViewSource, IFrameworkView> {
  CompositionTarget m_target{nullptr};

  IFrameworkView CreateView() { return *this; }

  void Initialize(CoreApplicationView const &) {}

  void Load(hstring const &) {}

  void Uninitialize() {}

  void Run() {
    CoreWindow window = CoreWindow::GetForCurrentThread();
    winrt::Windows::UI::Xaml::Controls::TextBox textbox; // Crashes here

    CoreDispatcher dispatcher = window.Dispatcher();
    dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
  }

  void SetWindow(CoreWindow const &) {
    Compositor compositor;
    ContainerVisual root = compositor.CreateContainerVisual();
    m_target = compositor.CreateTargetForCurrentView();
    m_target.Root(root);
  }
};

int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) { CoreApplication::Run(make<App>()); }

I've tried using window.Dispatcher().HasThreadAccess() to verify that I'm on the correct thread to be making UI calls, and it always returns true.

I've also tried calling RunAsync() from the window's Dispatcher and constructing a Xaml object in a lambda passed to this method, and it still has exactly the same result. HasThreadAccess returns true here too.

Can anyone explain to me where I'm going wrong here? Is constructing Xaml objects not supported in C++?

[edit]

Here's a sample project that reproduces the issue, again based on the default CoreWindow C++/WinRT template:

https://github.com/lyptt/CoreApp1


Solution

  • Turns out the CoreApplication-based template does not support anything from the Xaml namespace, as it's intended more towards providing a thin UWP layer for games, etc.

    To get Xaml support you need to use the full template instead, then things magically start to work.