2 * Copyright 1999, 2000 Juergen Schmied
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #ifndef __ROS_SHELL_UTILS_H
20 #define __ROS_SHELL_UTILS_H
24 #endif /* defined(__cplusplus) */
27 # define IID_PPV_ARG(Itype, ppType) IID_##Itype, reinterpret_cast<void**>((static_cast<Itype**>(ppType)))
28 # define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, reinterpret_cast<void**>((static_cast<Itype**>(ppType)))
30 # define IID_PPV_ARG(Itype, ppType) IID_##Itype, (void**)(ppType)
31 # define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, (void**)(ppType)
35 #define FAILED_UNEXPECTEDLY(hr) (FAILED(hr) && (Win32DbgPrint(__FILE__, __LINE__, "Unexpected failure %08x.\n", hr), TRUE))
37 #define FAILED_UNEXPECTEDLY(hr) FAILED(hr)
42 #endif /* defined(__cplusplus) */
46 class CComCreatorCentralInstance
49 static IUnknown
*s_pInstance
;
52 static HRESULT WINAPI
CreateInstance(void *pv
, REFIID riid
, LPVOID
*ppv
)
56 return CLASS_E_NOAGGREGATION
;
61 hr
= ATL::CComCreator
< T
>::CreateInstance(NULL
, IID_IUnknown
, &pObj
);
64 if (InterlockedCompareExchangePointer((PVOID
*)&s_pInstance
, pObj
, NULL
))
65 static_cast<IUnknown
*>(pObj
)->Release();
67 return s_pInstance
->QueryInterface(riid
, ppv
);
73 s_pInstance
->Release();
80 IUnknown
*CComCreatorCentralInstance
<T
>::s_pInstance
= NULL
;
82 #define DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(x) \
84 typedef CComCreatorCentralInstance< ATL::CComObject<x> > _CreatorClass;
89 class CComDebugObject
: public Base
92 CComDebugObject(void * = NULL
)
94 #if DEBUG_CCOMOBJECT_CREATION
95 DbgPrint("%S, this=%08p\n", __FUNCTION__
, static_cast<Base
*>(this));
100 virtual ~CComDebugObject()
102 this->FinalRelease();
103 _pAtlModule
->Unlock();
106 STDMETHOD_(ULONG
, AddRef
)()
108 int rc
= this->InternalAddRef();
109 #if DEBUG_CCOMOBJECT_REFCOUNTING
110 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__
, rc
);
115 STDMETHOD_(ULONG
, Release
)()
117 int rc
= this->InternalRelease();
119 #if DEBUG_CCOMOBJECT_REFCOUNTING
120 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__
, rc
);
125 #if DEBUG_CCOMOBJECT_DESTRUCTION
126 DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__
);
133 STDMETHOD(QueryInterface
)(REFIID iid
, void **ppvObject
)
135 return this->_InternalQueryInterface(iid
, ppvObject
);
138 static HRESULT WINAPI
CreateInstance(CComDebugObject
<Base
> **pp
)
140 CComDebugObject
<Base
> *newInstance
;
143 ATLASSERT(pp
!= NULL
);
147 hResult
= E_OUTOFMEMORY
;
149 ATLTRY(newInstance
= new CComDebugObject
<Base
>());
150 if (newInstance
!= NULL
)
152 newInstance
->SetVoid(NULL
);
153 newInstance
->InternalFinalConstructAddRef();
154 hResult
= newInstance
->_AtlInitialConstruct();
155 if (SUCCEEDED(hResult
))
156 hResult
= newInstance
->FinalConstruct();
157 if (SUCCEEDED(hResult
))
158 hResult
= newInstance
->_AtlFinalConstruct();
159 newInstance
->InternalFinalConstructRelease();
171 #ifdef DEBUG_CCOMOBJECT
172 # define _CComObject CComDebugObject
174 # define _CComObject CComObject
178 void ReleaseCComPtrExpectZero(CComPtr
<T
>& cptr
, BOOL forceRelease
= FALSE
)
182 int nrc
= cptr
->Release();
185 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc
);
190 nrc
= cptr
->Release();
198 template<class T
, class R
>
199 HRESULT
inline ShellDebugObjectCreator(REFIID riid
, R
** ppv
)
207 ATLTRY(obj
= new CComDebugObject
<T
>);
209 return E_OUTOFMEMORY
;
210 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
216 template<class T
, class R
>
217 HRESULT
inline ShellObjectCreator(REFIID riid
, R
** ppv
)
225 ATLTRY(obj
= new _CComObject
<T
>);
227 return E_OUTOFMEMORY
;
228 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
234 template<class T
, class R
>
235 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, R
** ppv
)
244 ATLTRY(obj
= new _CComObject
<T
>);
246 return E_OUTOFMEMORY
;
247 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
251 hResult
= obj
->Initialize();
255 *ppv
= result
.Detach();
261 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, void ** ppv
)
264 CComPtr
<IUnknown
> result
;
270 ATLTRY(obj
= new _CComObject
<T
>);
272 return E_OUTOFMEMORY
;
273 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
277 hResult
= obj
->Initialize();
281 *ppv
= result
.Detach();
286 template<class T
, class T1
>
287 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, void ** ppv
)
295 ATLTRY(obj
= new _CComObject
<T
>);
297 return E_OUTOFMEMORY
;
298 hResult
= obj
->QueryInterface(riid
, ppv
);
302 hResult
= obj
->Initialize(initArg1
);
309 template<class T
, class T1
, class T2
>
310 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, void ** ppv
)
318 ATLTRY(obj
= new _CComObject
<T
>);
320 return E_OUTOFMEMORY
;
321 hResult
= obj
->QueryInterface(riid
, ppv
);
325 hResult
= obj
->Initialize(initArg1
, initArg2
);
332 template<class T
, class T1
, class T2
, class T3
>
333 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, void ** ppv
)
341 ATLTRY(obj
= new _CComObject
<T
>);
343 return E_OUTOFMEMORY
;
344 hResult
= obj
->QueryInterface(riid
, ppv
);
348 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
);
355 template<class T
, class T1
, class R
>
356 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, R
** ppv
)
365 ATLTRY(obj
= new _CComObject
<T
>);
367 return E_OUTOFMEMORY
;
368 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
372 hResult
= obj
->Initialize(initArg1
);
376 *ppv
= result
.Detach();
381 template<class T
, class T1
, class T2
, class R
>
382 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, R
** ppv
)
391 ATLTRY(obj
= new _CComObject
<T
>);
393 return E_OUTOFMEMORY
;
394 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
398 hResult
= obj
->Initialize(initArg1
, initArg2
);
402 *ppv
= result
.Detach();
407 template<class T
, class T1
, class T2
, class T3
, class R
>
408 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, R
** ppv
)
417 ATLTRY(obj
= new _CComObject
<T
>);
419 return E_OUTOFMEMORY
;
420 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
424 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
);
428 *ppv
= result
.Detach();
433 template<class T
, class T1
, class T2
, class T3
, class T4
, class R
>
434 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, REFIID riid
, R
** ppv
)
443 ATLTRY(obj
= new _CComObject
<T
>);
445 return E_OUTOFMEMORY
;
446 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
450 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
);
454 *ppv
= result
.Detach();
459 template<class T
, class T1
, class T2
, class T3
, class T4
, class T5
, class R
>
460 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, T5 initArg5
, REFIID riid
, R
** ppv
)
469 ATLTRY(obj
= new _CComObject
<T
>);
471 return E_OUTOFMEMORY
;
472 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
476 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
, initArg5
);
480 *ppv
= result
.Detach();
485 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, LPCSTR pstrValue
)
487 pStrRet
->uType
= STRRET_CSTR
;
488 strcpy(pStrRet
->cStr
, pstrValue
);
492 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, LPCWSTR pwstrValue
)
494 ULONG cchr
= wcslen(pwstrValue
);
495 LPWSTR buffer
= static_cast<LPWSTR
>(CoTaskMemAlloc((cchr
+ 1) * sizeof(WCHAR
)));
497 return E_OUTOFMEMORY
;
499 pStrRet
->uType
= STRRET_WSTR
;
500 pStrRet
->pOleStr
= buffer
;
501 wcscpy(buffer
, pwstrValue
);
505 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, HINSTANCE hInstance
, DWORD resId
)
507 WCHAR Buffer
[MAX_PATH
];
509 if (!LoadStringW(hInstance
, resId
, Buffer
, MAX_PATH
))
512 return SHSetStrRet(pStrRet
, Buffer
);
515 #endif /* __cplusplus */
517 #define S_LESSTHAN 0xffff
519 #define S_GREATERTHAN S_FALSE
520 #define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
522 #endif /* __ROS_SHELL_UTILS_H */