aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2025-02-17 08:48:23 +1100
committerNeil <nyamatongwe@gmail.com>2025-02-17 08:48:23 +1100
commitdd58631f7a0193dd95523d1ebe4114753fef06c0 (patch)
tree6305ac65c588c555829c67d57eac998d56e48ef9
parent99497f846e812b5333eca87fe9f9812eab7daaf0 (diff)
downloadscintilla-mirror-dd58631f7a0193dd95523d1ebe4114753fef06c0.tar.gz
Switch to using ComPtr from WRL for render target code for simplicity and
familiarity.
-rw-r--r--scripts/HeaderOrder.txt1
-rw-r--r--win32/PlatWin.cxx55
-rw-r--r--win32/PlatWin.h11
-rw-r--r--win32/ScintillaWin.cxx122
-rw-r--r--win32/WinTypes.h19
5 files changed, 74 insertions, 134 deletions
diff --git a/scripts/HeaderOrder.txt b/scripts/HeaderOrder.txt
index eb0a16dd1..7274299b5 100644
--- a/scripts/HeaderOrder.txt
+++ b/scripts/HeaderOrder.txt
@@ -80,6 +80,7 @@
#include <shellscalingapi.h>
#include <zmouse.h>
#include <ole2.h>
+#include <wrl.h>
#include <d2d1_1.h>
#include <d3d11_1.h>
#include <dwrite_1.h>
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index c055f68f4..2eb5d2fcd 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -39,6 +39,9 @@
#include <windowsx.h>
#include <shellscalingapi.h>
+#include <wrl.h>
+using Microsoft::WRL::ComPtr;
+
#if !defined(DISABLE_D2D)
#define USE_D2D 1
#endif
@@ -143,9 +146,8 @@ void LoadD2DOnce() noexcept {
}
}
-HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept {
- device.reset();
- context.reset();
+HRESULT CreateD3D(D3D11Device &device) noexcept {
+ device = nullptr;
if (!fnDCD) {
return E_FAIL;
}
@@ -160,47 +162,34 @@ HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept {
D3D_FEATURE_LEVEL_9_1
};
- // Create device and context.
+ // Create device.
// Try for a hardware device but, if that fails, fall back to the Warp software rasterizer.
- D3D_FEATURE_LEVEL returnedFeatureLevel{};
- ID3D11Device *pDevice{};
- ID3D11DeviceContext *pContext{};
+ ComPtr<ID3D11Device> upDevice;
HRESULT hr = S_OK;
const D3D_DRIVER_TYPE typesToTry[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP };
for (const D3D_DRIVER_TYPE type : typesToTry) {
hr = fnDCD(nullptr,
type,
- 0,
+ {},
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
featureLevels,
ARRAYSIZE(featureLevels),
D3D11_SDK_VERSION,
- &pDevice,
- &returnedFeatureLevel,
- &pContext);
+ upDevice.GetAddressOf(),
+ nullptr,
+ nullptr);
if (SUCCEEDED(hr))
break;
}
if (FAILED(hr)) {
- Platform::DebugPrintf("Failed to create D3D11 device and context 0x%lx\n", hr);
+ Platform::DebugPrintf("Failed to create D3D11 device 0x%lx\n", hr);
return hr;
}
- // Ensure released
- std::unique_ptr<ID3D11Device, UnknownReleaser> upDevice(pDevice);
- std::unique_ptr<ID3D11DeviceContext, UnknownReleaser> upContext(pContext);
-
// Convert from D3D11 to D3D11.1
- hr = UniquePtrFromQI(upDevice.get(), __uuidof(ID3D11Device1), device);
+ hr = upDevice.As(&device);
if (FAILED(hr)) {
Platform::DebugPrintf("Failed to create D3D11.1 device 0x%lx\n", hr);
- return hr;
- }
- hr = UniquePtrFromQI(upContext.get(), __uuidof(ID3D11DeviceContext1), context);
- if (FAILED(hr)) {
- // Either both device and context or neither
- device.reset();
- Platform::DebugPrintf("Failed to create D3D11.1 device context 0x%lx\n", hr);
}
return hr;
}
@@ -216,13 +205,7 @@ bool LoadD2D() noexcept {
}
HRESULT CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, DCRenderTarget &dcRT) noexcept {
- dcRT.reset();
- ID2D1DCRenderTarget *pDCRT{};
- const HRESULT hr = pD2DFactory->CreateDCRenderTarget(renderTargetProperties, &pDCRT);
- if (SUCCEEDED(hr) && pDCRT) {
- dcRT.reset(pDCRT);
- }
- return hr;
+ return pD2DFactory->CreateDCRenderTarget(renderTargetProperties, dcRT.ReleaseAndGetAddressOf());
}
constexpr D2D_COLOR_F ColorFromColourAlpha(ColourRGBA colour) noexcept {
@@ -1659,9 +1642,9 @@ void SurfaceD2D::SetFontQuality(FontQuality extraFontFlag) {
fontQuality = extraFontFlag;
const D2D1_TEXT_ANTIALIAS_MODE aaMode = DWriteMapFontQuality(extraFontFlag);
if (aaMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE && renderingParams->customRenderingParams) {
- pRenderTarget->SetTextRenderingParams(renderingParams->customRenderingParams.get());
+ pRenderTarget->SetTextRenderingParams(renderingParams->customRenderingParams.Get());
} else if (renderingParams->defaultRenderingParams) {
- pRenderTarget->SetTextRenderingParams(renderingParams->defaultRenderingParams.get());
+ pRenderTarget->SetTextRenderingParams(renderingParams->defaultRenderingParams.Get());
}
pRenderTarget->SetTextAntialiasMode(aaMode);
}
@@ -3050,11 +3033,11 @@ public:
return false;
}
- if (const BrushSolid pBrushFill = BrushSolidCreate(pTarget.get(), fillColour)) {
+ if (const BrushSolid pBrushFill = BrushSolidCreate(pTarget.Get(), fillColour)) {
pTarget->FillGeometry(geometry.get(), pBrushFill.get());
}
- if (const BrushSolid pBrushStroke = BrushSolidCreate(pTarget.get(), strokeColour)) {
+ if (const BrushSolid pBrushStroke = BrushSolidCreate(pTarget.Get(), strokeColour)) {
pTarget->DrawGeometry(geometry.get(), pBrushStroke.get(), scale);
}
@@ -3605,7 +3588,7 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) {
hr = pDCRT->BindDC(pDrawItem->hDC, &rcItem);
if (SUCCEEDED(hr)) {
- surfaceItem->Init(pDCRT.get(), pDrawItem->hwndItem);
+ surfaceItem->Init(pDCRT.Get(), pDrawItem->hwndItem);
pDCRT->BeginDraw();
const PRectangle rcImage = PRectangle::FromInts(0, 0, images.GetWidth(), rcItem.bottom - rcItem.top);
surfaceItem->DrawRGBAImage(rcImage,
diff --git a/win32/PlatWin.h b/win32/PlatWin.h
index 1b5b7b1b9..192bdf6a7 100644
--- a/win32/PlatWin.h
+++ b/win32/PlatWin.h
@@ -71,17 +71,14 @@ extern bool LoadD2D() noexcept;
extern ID2D1Factory1 *pD2DFactory;
extern IDWriteFactory1 *pIDWriteFactory;
-using DCRenderTarget = std::unique_ptr<ID2D1DCRenderTarget, UnknownReleaser>;
-using HwndRenderTarget = std::unique_ptr<ID2D1HwndRenderTarget, UnknownReleaser>;
-using D2DeviceContext = std::unique_ptr<ID2D1DeviceContext, UnknownReleaser>;
+using DCRenderTarget = ComPtr<ID2D1DCRenderTarget>;
-using D3D11Device = std::unique_ptr<ID3D11Device1, UnknownReleaser>;
-using D3D11DeviceContext = std::unique_ptr<ID3D11DeviceContext1, UnknownReleaser>;
+using D3D11Device = ComPtr<ID3D11Device1>;
HRESULT CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, DCRenderTarget &dcRT) noexcept;
-extern HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept;
+extern HRESULT CreateD3D(D3D11Device &device) noexcept;
-using WriteRenderingParams = std::unique_ptr<IDWriteRenderingParams1, UnknownReleaser>;
+using WriteRenderingParams = ComPtr<IDWriteRenderingParams1>;
struct RenderingParams {
WriteRenderingParams defaultRenderingParams;
diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx
index dcfcde2f6..52ccf8709 100644
--- a/win32/ScintillaWin.cxx
+++ b/win32/ScintillaWin.cxx
@@ -43,6 +43,9 @@
#include <zmouse.h>
#include <ole2.h>
+#include <wrl.h>
+using Microsoft::WRL::ComPtr;
+
#if !defined(DISABLE_D2D)
#define USE_D2D 1
#endif
@@ -369,47 +372,44 @@ namespace Scintilla::Internal {
#if defined(USE_D2D)
+using HwndRenderTarget = ComPtr<ID2D1HwndRenderTarget>;
+
// There may be either a Hwnd or DC render target
struct RenderTargets {
HwndRenderTarget pHwndRT;
DCRenderTarget pDCRT;
- D2DeviceContext pDeviceContext;
+ ComPtr<ID2D1DeviceContext> pDeviceContext;
bool valid = true;
- ID2D1RenderTarget *RenderTarget() const noexcept {
+ [[nodiscard]] ID2D1RenderTarget *RenderTarget() const noexcept {
if (pHwndRT)
- return pHwndRT.get();
+ return pHwndRT.Get();
if (pDCRT)
- return pDCRT.get();
+ return pDCRT.Get();
if (pDeviceContext)
- return pDeviceContext.get();
+ return pDeviceContext.Get();
return nullptr;
}
void Release() noexcept {
- pHwndRT.reset();
- pDCRT.reset();
- pDeviceContext.reset();
+ pHwndRT = nullptr;
+ pDCRT = nullptr;
+ pDeviceContext = nullptr;
}
};
-using D2D1Device = std::unique_ptr<ID2D1Device, UnknownReleaser>;
-using DXGIDevice = std::unique_ptr<IDXGIDevice, UnknownReleaser>;
-
// These resources are device-dependent but not window-dependent
struct DirectDevice {
D3D11Device pDirect3DDevice;
- D3D11DeviceContext pDirect3DContext;
- D2D1Device pDirect2DDevice;
- DXGIDevice pDXGIDevice;
+ ComPtr<ID2D1Device> pDirect2DDevice;
+ ComPtr<IDXGIDevice> pDXGIDevice;
void Release() noexcept;
HRESULT CreateDevice() noexcept;
};
void DirectDevice::Release() noexcept {
- pDirect3DDevice.reset();
- pDirect3DContext.reset();
- pDirect2DDevice.reset();
- pDXGIDevice.reset();
+ pDirect3DDevice = nullptr;
+ pDirect2DDevice = nullptr;
+ pDXGIDevice = nullptr;
}
HRESULT DirectDevice::CreateDevice() noexcept {
@@ -417,31 +417,26 @@ HRESULT DirectDevice::CreateDevice() noexcept {
return E_FAIL;
}
- HRESULT hr = CreateD3D(pDirect3DDevice, pDirect3DContext);
+ HRESULT hr = CreateD3D(pDirect3DDevice);
if (FAILED(hr)) {
- Platform::DebugPrintf("Failed to create D3D device 0x%lx\n", hr);
return hr;
}
- hr = UniquePtrFromQI(pDirect3DDevice.get(), __uuidof(IDXGIDevice), pDXGIDevice);
+ hr = pDirect3DDevice.As(&pDXGIDevice);
if (FAILED(hr)) {
Platform::DebugPrintf("Failed to create DXGI device 0x%lx\n", hr);
return hr;
}
- ID2D1Device *pDirect2DDevice_{};
- hr = pD2DFactory->CreateDevice(pDXGIDevice.get(), &pDirect2DDevice_);
+ hr = pD2DFactory->CreateDevice(pDXGIDevice.Get(), pDirect2DDevice.ReleaseAndGetAddressOf());
if (FAILED(hr)) {
Platform::DebugPrintf("Failed to create D2D device 0x%lx\n", hr);
return hr;
}
- pDirect2DDevice.reset(pDirect2DDevice_);
return S_OK;
}
-using DXGISwapChain = std::unique_ptr<IDXGISwapChain1, UnknownReleaser>;
-
#endif
/**
@@ -492,7 +487,7 @@ class ScintillaWin :
#if defined(USE_D2D)
DirectDevice device;
- DXGISwapChain pDXGISwapChain;
+ ComPtr<IDXGISwapChain1> pDXGISwapChain;
RenderTargets targets;
// rendering parameters for current monitor
HMONITOR hCurrentMonitor;
@@ -764,25 +759,13 @@ void ScintillaWin::Finalise() {
#if defined(USE_D2D)
+namespace {
+
HRESULT CreateHwndRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties,
const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwndRenderTargetProperties, HwndRenderTarget &hwndRT) noexcept {
- hwndRT.reset();
- ID2D1HwndRenderTarget *pHwndRT{};
- const HRESULT hr = pD2DFactory->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, &pHwndRT);
- if (SUCCEEDED(hr) && pHwndRT) {
- hwndRT.reset(pHwndRT);
- }
- return hr;
+ return pD2DFactory->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, hwndRT.ReleaseAndGetAddressOf());
}
-HRESULT CreateDeviceContext(ID2D1Device *pDirect2DDevice, D2DeviceContext &deviceContext) noexcept {
- deviceContext.reset();
- ID2D1DeviceContext *pD2DC{};
- const HRESULT hr = pDirect2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &pD2DC);
- if (SUCCEEDED(hr) && pD2DC) {
- deviceContext.reset(pD2DC);
- }
- return hr;
}
bool ScintillaWin::UpdateRenderingParams(bool force) noexcept {
@@ -799,18 +782,17 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept {
return false;
}
- IDWriteRenderingParams *mrpTemp{};
- HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, &mrpTemp);
+ ComPtr<IDWriteRenderingParams> upMrp;
+ HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, upMrp.GetAddressOf());
if (FAILED(hr)) {
return false;
}
- std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> upMrp(mrpTemp);
// Cast to IDWriteRenderingParams1 so can call GetGrayscaleEnhancedContrast
WriteRenderingParams monitorRenderingParams{};
- hr = UniquePtrFromQI(upMrp.get(), __uuidof(IDWriteRenderingParams1), monitorRenderingParams);
+ hr = upMrp.As(&monitorRenderingParams);
- IDWriteRenderingParams1 *customClearTypeRenderingParams{};
+ WriteRenderingParams customClearTypeRenderingParams;
UINT clearTypeContrast = 0;
if (SUCCEEDED(hr) && monitorRenderingParams &&
::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0) != 0) {
@@ -822,14 +804,14 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept {
monitorRenderingParams->GetClearTypeLevel(),
monitorRenderingParams->GetPixelGeometry(),
monitorRenderingParams->GetRenderingMode(),
- &customClearTypeRenderingParams);
+ customClearTypeRenderingParams.GetAddressOf());
}
}
hCurrentMonitor = monitor;
deviceScaleFactor = Internal::GetDeviceScaleFactorWhenGdiScalingActive(hRootWnd);
renderingParams->defaultRenderingParams = std::move(monitorRenderingParams);
- renderingParams->customRenderingParams.reset(customClearTypeRenderingParams);
+ renderingParams->customRenderingParams = std::move(customClearTypeRenderingParams);
return true;
}
@@ -838,7 +820,7 @@ HRESULT ScintillaWin::Create3D() noexcept {
return S_OK;
}
targets.Release();
- pDXGISwapChain.reset();
+ pDXGISwapChain = nullptr;
device.Release();
const HRESULT hr = device.CreateDevice();
if (FAILED(hr)) {
@@ -873,7 +855,8 @@ void ScintillaWin::CreateRenderTarget() {
} else if (technology == Technology::DirectWrite1) {
HRESULT hr = Create3D(); // Need pDirect2DDevice
if (SUCCEEDED(hr)) {
- hr = CreateDeviceContext(device.pDirect2DDevice.get(), targets.pDeviceContext);
+ hr = device.pDirect2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ targets.pDeviceContext.ReleaseAndGetAddressOf());
if (FAILED(hr)) {
Platform::DebugPrintf("Failed CreateDeviceContext 0x%lx\n", hr);
} else {
@@ -910,11 +893,10 @@ void ScintillaWin::CreateRenderTarget() {
HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) {
assert(targets.pDeviceContext);
// Back buffer as an IDXGISurface
- IDXGISurface *dxgiBackBuffer_{};
- HRESULT hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer_));
+ ComPtr<IDXGISurface> dxgiBackBuffer;
+ HRESULT hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(dxgiBackBuffer.GetAddressOf()));
if (FAILED(hr))
return hr;
- std::unique_ptr<IDXGISurface, UnknownReleaser> dxgiBackBuffer(dxgiBackBuffer_);
const FLOAT dpiX = static_cast<FLOAT>(DpiForWindow(hwnd));
const FLOAT dpiY = dpiX;
@@ -923,14 +905,13 @@ HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) {
const D2D1_BITMAP_PROPERTIES1 bitmapProperties =
D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), dpiX, dpiY);
- ID2D1Bitmap1 *pDirect2DBackBuffer{};
- hr = targets.pDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer.get(), &bitmapProperties, &pDirect2DBackBuffer);
+ ComPtr<ID2D1Bitmap1> pDirect2DBackBuffer;
+ hr = targets.pDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer.Get(), &bitmapProperties, pDirect2DBackBuffer.GetAddressOf());
if (FAILED(hr))
return hr;
// Bitmap is render target
- targets.pDeviceContext->SetTarget(pDirect2DBackBuffer);
- ReleaseUnknown(pDirect2DBackBuffer);
+ targets.pDeviceContext->SetTarget(pDirect2DBackBuffer.Get());
return S_OK;
}
@@ -938,22 +919,20 @@ HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) {
HRESULT ScintillaWin::CreateSwapChain(HWND hwnd) {
// Sets pDXGISwapChain but only when each call succeeds
// Needs pDXGIDevice, pDirect3DDevice
- pDXGISwapChain.reset();
+ pDXGISwapChain = nullptr;
assert(device.pDXGIDevice);
// At each stage, place object in a unique_ptr to ensure release occurs
- IDXGIAdapter *dxgiAdapter_{};
- HRESULT hr = device.pDXGIDevice->GetAdapter(&dxgiAdapter_);
+ ComPtr<IDXGIAdapter> dxgiAdapter;
+ HRESULT hr = device.pDXGIDevice->GetAdapter(dxgiAdapter.GetAddressOf());
if (FAILED(hr))
return hr;
- std::unique_ptr<IDXGIAdapter, UnknownReleaser> dxgiAdapter(dxgiAdapter_);
- IDXGIFactory2 *dxgiFactory_{};
- hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory_));
+ ComPtr<IDXGIFactory2> dxgiFactory;
+ hr = dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.GetAddressOf()));
if (FAILED(hr))
return hr;
- std::unique_ptr<IDXGIFactory2, UnknownReleaser> dxgiFactory(dxgiFactory_);
DXGI_SWAP_CHAIN_DESC1 swapChainDesc{};
swapChainDesc.Width = 0;
@@ -969,14 +948,13 @@ HRESULT ScintillaWin::CreateSwapChain(HWND hwnd) {
swapChainDesc.Flags = 0;
// DXGI swap chain for window
- IDXGISwapChain1 *pSwapChain_{};
- hr = dxgiFactory->CreateSwapChainForHwnd(device.pDirect3DDevice.get(), hwnd, &swapChainDesc,
- nullptr, nullptr, &pSwapChain_);
+ ComPtr<IDXGISwapChain1> pSwapChain;
+ hr = dxgiFactory->CreateSwapChainForHwnd(device.pDirect3DDevice.Get(), hwnd, &swapChainDesc,
+ nullptr, nullptr, pSwapChain.GetAddressOf());
if (FAILED(hr))
return hr;
- DXGISwapChain pSwapChain(pSwapChain_);
- hr = SetBackBuffer(hwnd, pSwapChain.get());
+ hr = SetBackBuffer(hwnd, pSwapChain.Get());
if (FAILED(hr))
return hr;
@@ -1810,7 +1788,7 @@ void ScintillaWin::SizeWindow() {
targets.pDeviceContext->SetTarget(NULL); // ResizeBuffers fails if bitmap still owned by swap chain
hrResize = pDXGISwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
if (SUCCEEDED(hrResize)) {
- hrResize = SetBackBuffer(MainHWND(), pDXGISwapChain.get());
+ hrResize = SetBackBuffer(MainHWND(), pDXGISwapChain.Get());
} else {
Platform::DebugPrintf("Failed ResizeBuffers 0x%lx\n", hrResize);
}
@@ -3988,7 +3966,7 @@ LRESULT PASCAL ScintillaWin::CTWndProc(
// If above SUCCEEDED, then pCTRenderTarget not nullptr
assert(pCTRenderTarget);
if (pCTRenderTarget) {
- surfaceWindow->Init(pCTRenderTarget.get(), hWnd);
+ surfaceWindow->Init(pCTRenderTarget.Get(), hWnd);
pCTRenderTarget->BeginDraw();
}
#endif
diff --git a/win32/WinTypes.h b/win32/WinTypes.h
index 9c930bb7c..c0d6c558d 100644
--- a/win32/WinTypes.h
+++ b/win32/WinTypes.h
@@ -38,25 +38,6 @@ struct UnknownReleaser {
}
};
-// Wrap COM IUnknown::QueryInterface to produce std::unique_ptr objects to help
-// ensure safe reference counting.
-template<typename T>
-inline HRESULT UniquePtrFromQI(IUnknown *source, REFIID riid, std::unique_ptr<T, UnknownReleaser> &destination) noexcept {
- T *ptr{};
- HRESULT hr = E_FAIL;
- try {
- hr = source->QueryInterface(riid, reinterpret_cast<void **>(&ptr));
- } catch (...) {
- // Shouldn't have exceptions from QueryInterface but not marked noexcept
- }
- if (SUCCEEDED(hr)) {
- destination.reset(ptr);
- } else {
- destination.reset();
- }
- return hr;
-}
-
/// Find a function in a DLL and convert to a function pointer.
/// This avoids undefined and conditionally defined behaviour.
template<typename T>