diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-02-26 13:11:12 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-02-27 11:05:00 +0100 |
commit | ed40d477b2412d4f23540052ca0748028c6103e6 (patch) | |
tree | d6a0013c1441e3c7d1a136479756aed7f396d786 /include/systools | |
parent | f3fab0832b57677d8dfe1297ae7aba631b44cc30 (diff) |
Drop ComPtr and use sal::systools::COMReference
Change-Id: I9eb6d99d883b44943ad69c2c28d4e55716dc34f9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111673
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'include/systools')
-rw-r--r-- | include/systools/win32/comtools.hxx | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/include/systools/win32/comtools.hxx b/include/systools/win32/comtools.hxx index 9f8489b8faac..c37053c931b7 100644 --- a/include/systools/win32/comtools.hxx +++ b/include/systools/win32/comtools.hxx @@ -21,6 +21,7 @@ #include <string> #include <stdexcept> +#include <type_traits> #include <objbase.h> namespace sal::systools @@ -40,6 +41,12 @@ namespace sal::systools HRESULT hr_; }; + struct COM_QUERY_TAG {} constexpr COM_QUERY; + struct COM_QUERY_THROW_TAG {} constexpr COM_QUERY_THROW; + template <typename TAG> + constexpr bool is_COM_query_tag + = std::is_same_v<TAG, COM_QUERY_TAG> || std::is_same_v<TAG, COM_QUERY_THROW_TAG>; + /* A simple COM smart pointer template */ template <typename T> class COMReference @@ -59,6 +66,13 @@ namespace sal::systools addRef(); } + // Query from IUnknown*, using COM_QUERY or COM_QUERY_THROW tags + template <typename T2, typename TAG> + COMReference(const COMReference<T2>& p, TAG t) + : COMReference(p.QueryInterface<T>(t)) + { + } + COMReference<T>& operator=(const COMReference<T>& other) { other.addRef(); @@ -77,18 +91,31 @@ namespace sal::systools ~COMReference() { release(); } - template<typename InterfaceType> - COMReference<InterfaceType> QueryInterface(REFIID iid) + template <typename T2, typename TAG, std::enable_if_t<is_COM_query_tag<TAG>, int> = 0> + COMReference<T2> QueryInterface(TAG) const { - COMReference<InterfaceType> ip; + void* ip = nullptr; HRESULT hr = E_FAIL; if (com_ptr_) - hr = com_ptr_->QueryInterface(iid, reinterpret_cast<LPVOID*>(&ip)); + hr = com_ptr_->QueryInterface(__uuidof(T2), &ip); + + if constexpr (std::is_same_v<TAG, COM_QUERY_THROW_TAG>) + if (FAILED(hr)) + throw ComError("QueryInterface failed: Interface not supported!", hr); + return { static_cast<T2*>(ip), false }; + } + + COMReference<T>& CoCreateInstance(REFCLSID clsid, IUnknown* pOuter = nullptr, + DWORD nCtx = CLSCTX_ALL) + { + clear(); + HRESULT hr = ::CoCreateInstance(clsid, pOuter, nCtx, __uuidof(T), + reinterpret_cast<void**>(&com_ptr_)); if (FAILED(hr)) - throw ComError("QueryInterface failed: Interface not supported!", hr); + throw ComError("CoCreateInstance failed!", hr); - return ip; + return *this; } T* operator->() const { return com_ptr_; } @@ -105,11 +132,10 @@ namespace sal::systools T* get() const { return com_ptr_; } - COMReference<T>& clear() + void clear() { release(); com_ptr_ = nullptr; - return *this; } bool is() const { return (com_ptr_ != nullptr); } |