-
Notifications
You must be signed in to change notification settings - Fork 21
/
Com.h
128 lines (101 loc) · 2.84 KB
/
Com.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Clavier+
// Keyboard shortcuts manager
//
// Copyright (C) 2000-2008 Guillaume Ryder
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once
// Smart pointer to a COM object. Lightweight equivalent of CComPtr.
template<class T>
class CoPtr {
public:
CoPtr() : m_ptr(nullptr) {}
// Wrapper for CoCreateInstance().
explicit CoPtr(REFCLSID rclsid) {
if (FAILED(CoCreateInstance(rclsid, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&m_ptr)))) {
m_ptr = nullptr;
}
}
CoPtr(const CoPtr<T>& other) = delete;
CoPtr& operator =(const CoPtr<T>& other) = delete;
CoPtr(CoPtr<T>&& other) : m_ptr(other.m_ptr) {
other.m_ptr = nullptr;
}
~CoPtr() {
if (m_ptr) {
m_ptr->Release();
}
}
CoPtr<T>& operator =(CoPtr<T>&& other) {
if (m_ptr != other.m_ptr) {
this->~CoPtr();
m_ptr = other.m_ptr;
other.m_ptr = nullptr;
}
return *this;
}
T* operator ->() {
assert(m_ptr != nullptr);
return m_ptr;
}
operator bool() const {
return m_ptr != nullptr;
}
// const_cast to allow calling T methods declared as non-const.
T* get() const {
assert(m_ptr != nullptr);
return const_cast<T*>(m_ptr);
}
// Wrapper for QueryInterface().
template<class U>
CoPtr<U> queryInterface() {
U* queried = nullptr;
(*this)->QueryInterface(IID_PPV_ARGS(&queried));
return CoPtr<U>(queried);
}
// Returns a pointer to this pointer suitable for IID_PPV_ARGS.
// Available only if the pointer is null.
T** outPtr() {
assert(m_ptr == nullptr);
return &m_ptr;
}
void** outPtrVoid() {
return reinterpret_cast<void**>(outPtr());
}
private:
template<class U> friend class CoPtr;
explicit CoPtr(T* ptr) : m_ptr(ptr) {}
T* m_ptr;
};
// Smart pointer to a buffer to free with CoTaskMemFree().
// Takes the pointer type as argument instead of the type to support __unaligned.
template<class P>
class CoBuffer {
public:
CoBuffer() : m_ptr(nullptr) {}
explicit CoBuffer(P ptr) : m_ptr(ptr) {}
~CoBuffer() {
CoTaskMemFree(m_ptr);
}
operator P() { return m_ptr; }
operator const P() const { return m_ptr; }
// Returns a pointer to this pointer suitable for passing to an allocation function.
// Available only if the pointer is null.
P* outPtr() {
assert(m_ptr == nullptr);
return &m_ptr;
}
private:
P m_ptr;
};