12098d36a53253b2526b5fd077ce2f86bfd6aa56
[reactos.git] / reactos / sdk / lib / atl / atlcomcli.h
1 /*
2 * ReactOS ATL
3 *
4 * Copyright 2009 Andrew Hill <ash77@reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #pragma once
22
23 #include "atlcore.h"
24
25
26 #ifdef _MSC_VER
27 // It is common to use this in ATL constructors. They only store this for later use, so the usage is safe.
28 #pragma warning(disable:4355)
29 #endif
30
31 #ifndef _ATL_PACKING
32 #define _ATL_PACKING 8
33 #endif
34
35 #ifndef _ATL_FREE_THREADED
36 #ifndef _ATL_APARTMENT_THREADED
37 #ifndef _ATL_SINGLE_THREADED
38 #define _ATL_FREE_THREADED
39 #endif
40 #endif
41 #endif
42
43 #ifndef ATLTRY
44 #define ATLTRY(x) x;
45 #endif
46
47 #ifdef _ATL_DISABLE_NO_VTABLE
48 #define ATL_NO_VTABLE
49 #else
50 #define ATL_NO_VTABLE __declspec(novtable)
51 #endif
52
53 namespace ATL
54 {
55
56
57 template<class T>
58 class CComPtr
59 {
60 public:
61 T *p;
62 public:
63 CComPtr()
64 {
65 p = NULL;
66 }
67
68 CComPtr(T *lp)
69 {
70 p = lp;
71 if (p != NULL)
72 p->AddRef();
73 }
74
75 CComPtr(const CComPtr<T> &lp)
76 {
77 p = lp.p;
78 if (p != NULL)
79 p->AddRef();
80 }
81
82 ~CComPtr()
83 {
84 if (p != NULL)
85 p->Release();
86 }
87
88 T *operator = (T *lp)
89 {
90 if (p != NULL)
91 p->Release();
92 p = lp;
93 if (p != NULL)
94 p->AddRef();
95 return *this;
96 }
97
98 T *operator = (const CComPtr<T> &lp)
99 {
100 if (p != NULL)
101 p->Release();
102 p = lp.p;
103 if (p != NULL)
104 p->AddRef();
105 return *this;
106 }
107
108 void Release()
109 {
110 if (p != NULL)
111 {
112 p->Release();
113 p = NULL;
114 }
115 }
116
117 void Attach(T *lp)
118 {
119 if (p != NULL)
120 p->Release();
121 p = lp;
122 }
123
124 T *Detach()
125 {
126 T *saveP;
127
128 saveP = p;
129 p = NULL;
130 return saveP;
131 }
132
133 T **operator & ()
134 {
135 ATLASSERT(p == NULL);
136 return &p;
137 }
138
139 operator T * ()
140 {
141 return p;
142 }
143
144 T *operator -> ()
145 {
146 ATLASSERT(p != NULL);
147 return p;
148 }
149 };
150
151
152 class CComBSTR
153 {
154 public:
155 BSTR m_str;
156 public:
157 CComBSTR() :
158 m_str(NULL)
159 {
160 }
161
162 CComBSTR(LPCOLESTR pSrc)
163 {
164 if (pSrc == NULL)
165 m_str = NULL;
166 else
167 m_str = ::SysAllocString(pSrc);
168 }
169
170 CComBSTR(int length)
171 {
172 if (length == 0)
173 m_str = NULL;
174 else
175 m_str = ::SysAllocStringLen(NULL, length);
176 }
177
178 CComBSTR(int length, LPCOLESTR pSrc)
179 {
180 if (length == 0)
181 m_str = NULL;
182 else
183 m_str = ::SysAllocStringLen(pSrc, length);
184 }
185
186 CComBSTR(PCSTR pSrc)
187 {
188 if (pSrc)
189 {
190 int len = MultiByteToWideChar(CP_THREAD_ACP, 0, pSrc, -1, NULL, 0);
191 m_str = ::SysAllocStringLen(NULL, len - 1);
192 if (m_str)
193 {
194 int res = MultiByteToWideChar(CP_THREAD_ACP, 0, pSrc, -1, m_str, len);
195 ATLASSERT(res == len);
196 if (res != len)
197 {
198 ::SysFreeString(m_str);
199 m_str = NULL;
200 }
201 }
202 }
203 else
204 {
205 m_str = NULL;
206 }
207 }
208
209 CComBSTR(const CComBSTR &other)
210 {
211 m_str = other.Copy();
212 }
213
214 CComBSTR(REFGUID guid)
215 {
216 OLECHAR szGuid[40];
217 ::StringFromGUID2(guid, szGuid, 40);
218 m_str = ::SysAllocString(szGuid);
219 }
220
221 ~CComBSTR()
222 {
223 ::SysFreeString(m_str);
224 m_str = NULL;
225 }
226
227 operator BSTR () const
228 {
229 return m_str;
230 }
231
232 BSTR *operator & ()
233 {
234 return &m_str;
235 }
236
237 CComBSTR &operator = (const CComBSTR &other)
238 {
239 ::SysFreeString(m_str);
240 m_str = other.Copy();
241 return *this;
242 }
243
244 BSTR Copy() const
245 {
246 if (!m_str)
247 return NULL;
248 return ::SysAllocStringLen(m_str, ::SysStringLen(m_str));
249 }
250
251 HRESULT CopyTo(BSTR *other) const
252 {
253 if (!other)
254 return E_POINTER;
255 *other = Copy();
256 return S_OK;
257 }
258
259 bool LoadString(HMODULE module, DWORD uID)
260 {
261 ::SysFreeString(m_str);
262 m_str = NULL;
263 const wchar_t *ptr = NULL;
264 int len = ::LoadStringW(module, uID, (PWSTR)&ptr, 0);
265 if (len)
266 m_str = ::SysAllocStringLen(ptr, len);
267 return m_str != NULL;
268 }
269
270 unsigned int Length() const
271 {
272 return ::SysStringLen(m_str);
273 }
274
275 unsigned int ByteLength() const
276 {
277 return ::SysStringByteLen(m_str);
278 }
279 };
280
281
282 class CComVariant : public tagVARIANT
283 {
284 public:
285 CComVariant()
286 {
287 ::VariantInit(this);
288 }
289
290 ~CComVariant()
291 {
292 Clear();
293 }
294
295 HRESULT Clear()
296 {
297 return ::VariantClear(this);
298 }
299 };
300
301
302
303 }; // namespace ATL
304
305 #ifndef _ATL_NO_AUTOMATIC_NAMESPACE
306 using namespace ATL;
307 #endif //!_ATL_NO_AUTOMATIC_NAMESPACE
308