0
votes

I am attempting to port the DirectX11/XAML UWP template over to a C++-WinRT version... where EVERYTHING is done via C++-WinRT and I can turn off CX.

I'm currently stuck on how to ResizeBuffers on the swapchain. I keep getting the error that says I haven't released all of the buffer references. If I comment out anything to do with resizing buffers and just hardcode in a size, the app works. So... I am probably doing something wrong.

I believe it has to do with the new winrt::com_ptr. There is no Reset method like on the WRL ComPtr. I have set them to nullptr just like in the original C++/CX templates, but that doesn't seem to be enough.

Other things I've had to do that may have an affect on what's going on:

  1. The DeviceResources class is now a C++/WinRT class that I am creating by default in all of the other classes (SampleScene3DRenderer, DirectXPage, & Main) using the nullptr_t parameter. That way, I can create it in the DirectXPage, pass in the swapChainPanel reference, then pass this one DeviceResources instance to all of the other classes I create.

  2. There's one spot in the DirectX initialization where you have to pass in a **IUnknown. The docs for C++/WinRT mention using a function called winrt::get_unknown to return an *IUnknown. I couldn't get it to work for the following DWriteCreateFactory method so I tried it this way:

     DX::ThrowIfFailed(
        DWriteCreateFactory(
           DWRITE_FACTORY_TYPE_SHARED,
           __uuidof(IDWriteFactory3),
           reinterpret_cast<::IUnknown**>(m_dwriteFactory.put())
        )
    );
    

I'm not sure what else to do. Only the swapchain resizing doesn't work. I'm doing this on PC (not windows phone).

1
RE: 1 - You don't have to stop using Microsoft::WRL:ComPtr to use C++/WinRT. It builds just fine without /ZW. You can use winrt::com_ptr instead, but it has nothing to do with removing /ZW. RE: 2 - Have you tried using static_cast<::IUnknown*>(winrt::get_abi(window))? - Chuck Walbourn
@ChuckWalbourn: Shouldn't this be winrt::put_abi here? - IInspectable
Ah, I thought so... I was just in namespace hell for a while with the ambiguous Windows namespace error. - Lee McPherson

1 Answers

4
votes

The DWriteCreateFactory call using winrt::com_ptr<T> and the put member above is correct. Also using nullptr assignment is the correct way to reset a com_ptr<T>.

com_ptr<IUnknown> ptr = ...

assert(ptr);
ptr = nullptr;
assert(!ptr);

You can also use winrt::check_hresult rather than ThrowIfFailed if you wish to be consistent with how C++/WinRT reports errors. Here's a simple DirectX example written entirely with C++/WinRT:

https://github.com/kennykerr/cppwinrt/blob/master/Store/Direct2D/App.cpp