aboutsummaryrefslogtreecommitdiffstats
path: root/common/comptr.h
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-09-29 13:29:51 -0700
committerChris Robinson <[email protected]>2023-09-29 13:29:51 -0700
commit014fb03d8353c8a495b4df4c44a7f29c93adba79 (patch)
treeb3a11f3b2f8aec1e1d8a156044cfb60a9ecd07d8 /common/comptr.h
parentfbe9d42d8a48330bb3ccc3966d1d94b438565f35 (diff)
Add a wrapper for COM initialization
This helps ensure COM is initialized and deinitialized in order relative to other objects (e.g. ComPtr).
Diffstat (limited to 'common/comptr.h')
-rw-r--r--common/comptr.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/common/comptr.h b/common/comptr.h
index 5a733ea2..9f8fd294 100644
--- a/common/comptr.h
+++ b/common/comptr.h
@@ -7,6 +7,44 @@
#include <utility>
#include <variant>
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <objbase.h>
+
+struct ComWrapper {
+ HRESULT mStatus{};
+
+ ComWrapper(void *reserved, DWORD coinit)
+ : mStatus{CoInitializeEx(reserved, coinit)}
+ { }
+ ComWrapper(DWORD coinit=COINIT_APARTMENTTHREADED)
+ : mStatus{CoInitializeEx(nullptr, coinit)}
+ { }
+ ComWrapper(ComWrapper&& rhs) { mStatus = std::exchange(rhs.mStatus, E_FAIL); }
+ ComWrapper(const ComWrapper&) = delete;
+ ~ComWrapper() { if(SUCCEEDED(mStatus)) CoUninitialize(); }
+
+ ComWrapper& operator=(ComWrapper&& rhs)
+ {
+ if(SUCCEEDED(mStatus))
+ CoUninitialize();
+ mStatus = std::exchange(rhs.mStatus, E_FAIL);
+ return *this;
+ }
+ ComWrapper& operator=(const ComWrapper&) = delete;
+
+ HRESULT status() const noexcept { return mStatus; }
+ explicit operator bool() const noexcept { return SUCCEEDED(status()); }
+
+ void uninit()
+ {
+ if(SUCCEEDED(mStatus))
+ CoUninitialize();
+ mStatus = E_FAIL;
+ }
+};
+
+
template<typename T>
struct ComPtr {
using element_type = T;