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
));
217 HRESULT
inline ShellObjectCreator(REFIID riid
, void ** ppv
)
219 _CComObject
<T
> *pobj
;
222 hResult
= _CComObject
<T
>::CreateInstance(&pobj
);
226 pobj
->AddRef(); /* CreateInstance returns object with 0 ref count */
228 hResult
= pobj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
230 pobj
->Release(); /* In case of failure the object will be released */
236 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, void ** ppv
)
238 _CComObject
<T
> *pobj
;
241 hResult
= _CComObject
<T
>::CreateInstance(&pobj
);
245 pobj
->AddRef(); /* CreateInstance returns object with 0 ref count */
247 hResult
= pobj
->Initialize();
249 if (SUCCEEDED(hResult
))
250 hResult
= pobj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
252 pobj
->Release(); /* In case of failure the object will be released */
257 template<class T
, class T1
>
258 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, void ** ppv
)
260 _CComObject
<T
> *pobj
;
263 hResult
= _CComObject
<T
>::CreateInstance(&pobj
);
267 pobj
->AddRef(); /* CreateInstance returns object with 0 ref count */
269 hResult
= pobj
->Initialize(initArg1
);
271 if (SUCCEEDED(hResult
))
272 hResult
= pobj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
274 pobj
->Release(); /* In case of failure the object will be released */
279 template<class T
, class T1
, class T2
>
280 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, void ** ppv
)
282 _CComObject
<T
> *pobj
;
285 hResult
= _CComObject
<T
>::CreateInstance(&pobj
);
289 pobj
->AddRef(); /* CreateInstance returns object with 0 ref count */
291 hResult
= pobj
->Initialize(initArg1
, initArg2
);
293 if (SUCCEEDED(hResult
))
294 hResult
= pobj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
296 pobj
->Release(); /* In case of failure the object will be released */
301 template<class T
, class T1
, class T2
, class T3
>
302 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, void ** ppv
)
304 _CComObject
<T
> *pobj
;
307 hResult
= _CComObject
<T
>::CreateInstance(&pobj
);
311 pobj
->AddRef(); /* CreateInstance returns object with 0 ref count */
313 hResult
= pobj
->Initialize(initArg1
, initArg2
, initArg3
);
315 if (SUCCEEDED(hResult
))
316 hResult
= pobj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
318 pobj
->Release(); /* In case of failure the object will be released */
323 template<class T
, class T1
, class T2
, class T3
, class T4
>
324 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, REFIID riid
, void ** ppv
)
326 _CComObject
<T
> *pobj
;
329 hResult
= _CComObject
<T
>::CreateInstance(&pobj
);
333 pobj
->AddRef(); /* CreateInstance returns object with 0 ref count */
335 hResult
= pobj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
);
337 if (SUCCEEDED(hResult
))
338 hResult
= pobj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
340 pobj
->Release(); /* In case of failure the object will be released */
345 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, LPCSTR pstrValue
)
347 pStrRet
->uType
= STRRET_CSTR
;
348 strcpy(pStrRet
->cStr
, pstrValue
);
352 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, LPCWSTR pwstrValue
)
354 ULONG cchr
= wcslen(pwstrValue
);
355 LPWSTR buffer
= static_cast<LPWSTR
>(CoTaskMemAlloc((cchr
+ 1) * sizeof(WCHAR
)));
357 return E_OUTOFMEMORY
;
359 pStrRet
->uType
= STRRET_WSTR
;
360 pStrRet
->pOleStr
= buffer
;
361 wcscpy(buffer
, pwstrValue
);
365 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, HINSTANCE hInstance
, DWORD resId
)
367 WCHAR Buffer
[MAX_PATH
];
369 if (!LoadStringW(hInstance
, resId
, Buffer
, MAX_PATH
))
372 return SHSetStrRet(pStrRet
, Buffer
);
375 #endif /* __cplusplus */
377 #define S_LESSTHAN 0xffff
379 #define S_GREATERTHAN S_FALSE
380 #define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
382 #endif /* __ROS_SHELL_UTILS_H */