diff options
author | Chris Robinson <[email protected]> | 2023-09-29 13:29:51 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2023-09-29 13:29:51 -0700 |
commit | 014fb03d8353c8a495b4df4c44a7f29c93adba79 (patch) | |
tree | b3a11f3b2f8aec1e1d8a156044cfb60a9ecd07d8 /common/comptr.h | |
parent | fbe9d42d8a48330bb3ccc3966d1d94b438565f35 (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.h | 38 |
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; |