summaryrefslogtreecommitdiff
path: root/include/systools
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-02-26 13:11:12 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2021-02-27 11:05:00 +0100
commited40d477b2412d4f23540052ca0748028c6103e6 (patch)
treed6a0013c1441e3c7d1a136479756aed7f396d786 /include/systools
parentf3fab0832b57677d8dfe1297ae7aba631b44cc30 (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.hxx42
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); }