Not able to create new object of DesktopWindowXamlSource after closing one

Shyam Butani 160 Reputation points
2024-06-18T05:49:24.7766667+00:00

Hi,

I'm working on Win32 application with Xaml Island. I'm facing the issue with DesktopWindowXamlSource.

If I create two objects of DesktopWindowXamlSource, it's working as expected.

However, If I create one object and close it using Close() method. After that, when I try to create another object, It crashes with below error.

WinRT originate error - 0x8000FFFF : 'Cannot activate WindowsXamlManager. Previous instance is still closing, please drain the Dispatcher before continue.

Would you help me understand the issue here, and how to achieve something like [ create obj1, close obj1, create obj2 ]?

Below is the sample code snippet to reproduce it:

int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
    // ... create window(s) using CreateWindow and get handle(s)

    DesktopWindowXamlSource desktopSource;

    auto interop = desktopSource.as<IDesktopWindowXamlSourceNative>();

    check_hresult(interop->AttachToWindow(_hWnd));

    HWND hWndXamlIsland = nullptr;

    interop->get_WindowHandle(&hWndXamlIsland);

    SetWindowPos(hWndXamlIsland, 0, 0, 0, rec_width, rec_height, SWP_SHOWWINDOW);

    //Windows::UI::Xaml::Controls::StackPanel xamlContainer;
    //Windows::UI::Xaml::Controls::TextBlock textblock;

    //textblock.Text(L"Hello World! 1234567890");
    //textblock.Margin({ 100, 100, 100, 100 });

    //xamlContainer.Children().Append(textblock);

    //xamlContainer.UpdateLayout();
    //desktopSource.Content(xamlContainer);

    ShowWindow(_hWnd, nCmdShow);

    desktopSource.Close(); // --------- Closing here ------------


    DesktopWindowXamlSource desktopSource1;

    auto interop1 = desktopSource1.as<IDesktopWindowXamlSourceNative>();

    check_hresult(interop1->AttachToWindow(_hWnd));

    HWND hWndXamlIsland1 = nullptr;

    interop1->get_WindowHandle(&hWndXamlIsland1);

    SetWindowPos(hWndXamlIsland1, 0, 0, 0, rec_width, rec_height, SWP_SHOWWINDOW);

    //Windows::UI::Xaml::Controls::StackPanel xamlContainer1;
    //Windows::UI::Xaml::Controls::TextBlock textblock1;

    //textblock1.Text(L"Hello World!");
    //textblock1.Margin({ 100, 100, 100, 100 });

    //xamlContainer1.Children().Append(textblock1);

    //xamlContainer1.UpdateLayout();
    //desktopSource1.Content(xamlContainer1);


    //Message loop:
    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

Thanks.

Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
743 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,491 questions
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 12,071 Reputation points Microsoft Vendor
    2024-06-19T03:02:50.7933333+00:00

    Hello @Shyam Butani,

    It works for me that calling WindowsXamlManager winxamlmanager = WindowsXamlManager::InitializeForCurrentThread(); explicitly firstly like Use the XAML hosting API to host a WinRT XAML control does.

    // Begin XAML Island section.
    
    // The call to winrt::init_apartment initializes COM; by default, in a multithreaded apartment.
    winrt::init_apartment(apartment_type::single_threaded);
    
    // Initialize the XAML framework's core window for the current thread.
    WindowsXamlManager winxamlmanager = WindowsXamlManager::InitializeForCurrentThread();
    
    /////////////////////////////////////////////////////////////////////
    DesktopWindowXamlSource desktopSource1;
    
    auto interop1 = desktopSource1.as<IDesktopWindowXamlSourceNative>();
    
    check_hresult(interop1->AttachToWindow(_hWnd));
    
    HWND hWndXamlIsland1 = nullptr;
    
    interop1->get_WindowHandle(&hWndXamlIsland1);
    
    SetWindowPos(hWndXamlIsland1, 0, 0, 0, 255, 255, SWP_SHOWWINDOW);
    
    ShowWindow(_hWnd, nCmdShow);
    
    desktopSource1.Close();
    /////////////////////////////////////////////////////////////////////
    
    // This DesktopWindowXamlSource is the object that enables a non-UWP desktop application 
    // to host WinRT XAML controls in any UI element that is associated with a window handle (HWND).
    DesktopWindowXamlSource desktopSource;
    

0 additional answers

Sort by: Most helpful