Lee McPherson
Lee McPherson

Reputation: 931

C++-WinRT's com_ptr reset?

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).

Upvotes: 0

Views: 1503

Answers (2)

elika kohen
elika kohen

Reputation: 157

I had the same problem. Now, it works after I moved my include for unknwn.h to before all of the winrt includes.

// pch.h
#pragma once

#include <unknwn.h>
#include <winrt/windows.globalization.datetimeformatting.h>
#include <winrt/windows.web.syndication.h>



#include <winrt/windows.foundation.collections.h>
#include <winrt/windows.foundation.numerics.h>


#include <winrt/windows.graphics.display.h>


#include <winrt/windows.applicationmodel.h>
#include <winrt/windows.applicationmodel.activation.h>
#include <winrt/windows.applicationmodel.core.h>


#include <winrt/windows.ui.h>
// #include <winrt/Windows.ui.core.h>
#include <winrt/Windows.UI.Core.h>
#include <winrt/windows.ui.composition.h>

#include <iostream>
#include <d2d1_1.h>
#include <d3d11.h>
#include <d3d11_2.h>
#include <d3d12.h>
#include <dxgi1_2.h>

Upvotes: 0

Kenny Kerr
Kenny Kerr

Reputation: 3115

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

Upvotes: 8

Related Questions