comwinui-3c++-winrtwindows-app-sdkxaml-islands

Cast DesktopWindowXamlSource to IDesktopWindowXamlSourceNative fails with E_NOINTERFACE


I'm trying to use XAML Islands for WinUI 3 in a Win32 application.

After creating a new Win32 Desktop application from the File -> New Projet wizard, and:

  1. Installing the latest versions of the Windows App SDK and CppWinRT NuGet packages (which are versions 1.4.231115000 and 2.0.230706.1 respectively),
  2. Unloading the project, then adding <WindowsPackageType>None</WindowsPackageType> to the <PropertyGroup Label="Globals"> section of project file, and
  3. Replacing the contents of the main .cpp file with the following:
#include "framework.h"
#include "WinUI3XamlIslandsWin32.h"

#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
#include <winrt/Microsoft.UI.Dispatching.h>
#include <winrt/Microsoft.UI.Xaml.Hosting.h>
#include <cassert>

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    winrt::init_apartment(winrt::apartment_type::single_threaded);
    auto dispatcherQueueController = winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread();
    auto windowsXamlManager = winrt::Microsoft::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread();
    winrt::Microsoft::UI::Xaml::Hosting::DesktopWindowXamlSource desktopWindowXamlSource;
    auto interop = desktopWindowXamlSource.as<IDesktopWindowXamlSourceNative>();
    assert(interop != nullptr);
    return EXIT_SUCCESS;
}

If you run this program, it can successfully create the DesktopWindowXamlSource, but the line desktopWindowXamlSource.as<IDesktopWindowXamlSourceNative>() fails with E_NOINTERFACE. Indeed, if you try winrt::get_interfaces(desktopWindowXamlSource) to list the interfaces the DesktopWindowXamlSource supports, it only lists:

Is there some extra step of setup necessary to allow the DesktopWindowXamlSource to be casted to the IDesktopWindowXamlSourceNative interface?

I've created a sample project at https://github.com/litherum/WinUI3XamlIslandsWin32 demonstrating the problem.


Solution

  • It looks like WinUI 3 changed how XAML Islands work.

    You can convert between HWNDs and WindowIDs by GetWindowFromWindowId() and GetWindowIdFromWindow().