question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unable to implement classic COM interface on XAML component with C++/WinRT

See original GitHub issue

Describe the bug When creating a XAML control/page, it’s not possible to make it implement a classic COM interface (as C++/WinRT does it, by appending it to the base template arguments: Something : SomethingT<Something, IMyClassicInterface>) because the XAML compiler codegen does not account for this case.

Steps to reproduce the bug

  1. Create a new blank C++/WinRT UWP app in VS
  2. Open MainPage.h, and add the following code:
    • Include <windows.ui.xaml.media.dxinterop.h>.
    • Change the struct declaration to struct MainPage : MainPageT<MainPage, ISwapChainPanelNative>.
    • Add IFACEMETHOD(SetSwapChain)(IDXGISwapChain*) noexcept; to the struct members.
  3. In MainPage.cpp, add the implementation:
    IFACEMETHODIMP MainPage::SetSwapChain(IDXGISwapChain*) noexcept
    {
        // dummy implementation
        return S_OK;
    }
    
  4. Try building the app.
  5. Observe compiler errors.

Expected behavior The app builds fine and a consumer is able to cast the XAML component to ISwapChainPanelNative and call the method provided by that interface.

Screenshots image

Version Info

NuGet package version: [Microsoft.Windows.CppWinRT 2.0.200921.6]

Windows app type:

UWP Win32
Yes Yes
Windows 10 version Saw the problem?
Insider Build (xxxxx)
May 2020 Update (19041) Yes
November 2019 Update (18363)
May 2019 Update (18362)
October 2018 Update (17763)
April 2018 Update (17134)
Fall Creators Update (16299)
Creators Update (15063)
Device form factor Saw the problem?
Desktop Yes
Xbox
Surface Hub
IoT

Additional context I replied Yes to the app type being Win32 because this issue showed up in system XAML islands while implementing IInitializeWithWindow to pass on a window handle to MessageDialog from my hosting code to the XAML code. I’m using MessageDialog because of ContentDialog’s limitation of one dialog open at a time per thread. Implementing threading proved to be a huge pain, so I’ve decided on using MessageDialog for now.

The bug is caused by this line in MainPage.xaml.g.hpp:

template struct MainPageT<struct MainPage>;

It tries to specialize MainPageT using different parameters than what I used in my declaration, and since the class uses CRTP, it tries to cast this back to MainPage, but because MainPage actually inherits from a different type (different template instantiations are effectively different types), the cast fails.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:2
  • Comments:13 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
DHowettcommented, Nov 24, 2020

@sylveon There was a brief but real moment when I realized I was here because I was also implementing IInitializeWithWindow in a XAML islands application that I was quite crestfallen because these are the depths to which we must sink.

Why does the XAML generated header need to forcibly instantiate this template anyway? Does it not suffice to let the consumer do it?

0reactions
sylveoncommented, Aug 4, 2023

I really don’t recommend it, it’s extremely fragile.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How do I use C++/WinRT to implement a classic COM ...
The C++/WinRT library can be used to implement both Windows Runtime interfaces as well as classic COM interfaces. One feature of classic COM ......
Read more >
Cannot use an Xaml component from a C# WinRT ...
So I finally found the solution we have to register against CLRHost.dll instead of the Runtime Component Winmd file.
Read more >
Windows Runtime
Windows Runtime (WinRT) is a platform-agnostic component and application architecture first introduced in Windows 8 and Windows Server 2012 in 2012.
Read more >
Native WinRT Inheritance
UI.Xaml.Application class, and called its Application.Run method. ... and classic COM never supported implementation inheritance.
Read more >
What is Actually the Universal Windows Platform and what ...
UWP XAML controls – the controls that you use in your UWP apps, they're also part of Windows 10/11. WinRT – the Windows...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found