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
);
74 ref
= s_pInstance
->Release();
81 IUnknown
*CComCreatorCentralInstance
<T
>::s_pInstance
= NULL
;
83 #define DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(x) \
85 typedef CComCreatorCentralInstance< ATL::CComObject<x> > _CreatorClass;
90 class CComDebugObject
: public Base
93 CComDebugObject(void * = NULL
)
95 #if DEBUG_CCOMOBJECT_CREATION
96 DbgPrint("%S, this=%08p\n", __FUNCTION__
, static_cast<Base
*>(this));
101 virtual ~CComDebugObject()
103 this->FinalRelease();
104 _pAtlModule
->Unlock();
107 STDMETHOD_(ULONG
, AddRef
)()
109 int rc
= this->InternalAddRef();
110 #if DEBUG_CCOMOBJECT_REFCOUNTING
111 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__
, rc
);
116 STDMETHOD_(ULONG
, Release
)()
118 int rc
= this->InternalRelease();
120 #if DEBUG_CCOMOBJECT_REFCOUNTING
121 DbgPrint("%s, RefCount is now %d(--)! \n", __FUNCTION__
, rc
);
126 #if DEBUG_CCOMOBJECT_DESTRUCTION
127 DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__
);
134 STDMETHOD(QueryInterface
)(REFIID iid
, void **ppvObject
)
136 return this->_InternalQueryInterface(iid
, ppvObject
);
139 static HRESULT WINAPI
CreateInstance(CComDebugObject
<Base
> **pp
)
141 CComDebugObject
<Base
> *newInstance
;
144 ATLASSERT(pp
!= NULL
);
148 hResult
= E_OUTOFMEMORY
;
150 ATLTRY(newInstance
= new CComDebugObject
<Base
>());
151 if (newInstance
!= NULL
)
153 newInstance
->SetVoid(NULL
);
154 newInstance
->InternalFinalConstructAddRef();
155 hResult
= newInstance
->_AtlInitialConstruct();
156 if (SUCCEEDED(hResult
))
157 hResult
= newInstance
->FinalConstruct();
158 if (SUCCEEDED(hResult
))
159 hResult
= newInstance
->_AtlFinalConstruct();
160 newInstance
->InternalFinalConstructRelease();
172 #ifdef DEBUG_CCOMOBJECT
173 # define _CComObject CComDebugObject
175 # define _CComObject CComObject
179 void ReleaseCComPtrExpectZero(CComPtr
<T
>& cptr
, BOOL forceRelease
= FALSE
)
183 int nrc
= cptr
->Release();
186 DbgPrint("WARNING: Unexpected RefCount > 0 (%d)!\n", nrc
);
191 nrc
= cptr
->Release();
199 template<class T
, class R
>
200 HRESULT
inline ShellDebugObjectCreator(REFIID riid
, R
** ppv
)
208 ATLTRY(obj
= new CComDebugObject
<T
>);
210 return E_OUTOFMEMORY
;
211 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
217 template<class T
, class R
>
218 HRESULT
inline ShellObjectCreator(REFIID riid
, R
** ppv
)
226 ATLTRY(obj
= new _CComObject
<T
>);
228 return E_OUTOFMEMORY
;
229 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(ppv
));
235 template<class T
, class R
>
236 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, R
** ppv
)
245 ATLTRY(obj
= new _CComObject
<T
>);
247 return E_OUTOFMEMORY
;
248 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
252 hResult
= obj
->Initialize();
256 *ppv
= result
.Detach();
262 HRESULT
inline ShellObjectCreatorInit(REFIID riid
, void ** ppv
)
265 CComPtr
<IUnknown
> result
;
271 ATLTRY(obj
= new _CComObject
<T
>);
273 return E_OUTOFMEMORY
;
274 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
278 hResult
= obj
->Initialize();
282 *ppv
= result
.Detach();
287 template<class T
, class T1
>
288 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, void ** ppv
)
296 ATLTRY(obj
= new _CComObject
<T
>);
298 return E_OUTOFMEMORY
;
299 hResult
= obj
->QueryInterface(riid
, ppv
);
303 hResult
= obj
->Initialize(initArg1
);
310 template<class T
, class T1
, class T2
>
311 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, void ** ppv
)
319 ATLTRY(obj
= new _CComObject
<T
>);
321 return E_OUTOFMEMORY
;
322 hResult
= obj
->QueryInterface(riid
, ppv
);
326 hResult
= obj
->Initialize(initArg1
, initArg2
);
333 template<class T
, class T1
, class T2
, class T3
>
334 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, void ** ppv
)
342 ATLTRY(obj
= new _CComObject
<T
>);
344 return E_OUTOFMEMORY
;
345 hResult
= obj
->QueryInterface(riid
, ppv
);
349 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
);
356 template<class T
, class T1
, class R
>
357 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, REFIID riid
, R
** ppv
)
366 ATLTRY(obj
= new _CComObject
<T
>);
368 return E_OUTOFMEMORY
;
369 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
373 hResult
= obj
->Initialize(initArg1
);
377 *ppv
= result
.Detach();
382 template<class T
, class T1
, class T2
, class R
>
383 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, REFIID riid
, R
** ppv
)
392 ATLTRY(obj
= new _CComObject
<T
>);
394 return E_OUTOFMEMORY
;
395 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
399 hResult
= obj
->Initialize(initArg1
, initArg2
);
403 *ppv
= result
.Detach();
408 template<class T
, class T1
, class T2
, class T3
, class R
>
409 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, REFIID riid
, R
** ppv
)
418 ATLTRY(obj
= new _CComObject
<T
>);
420 return E_OUTOFMEMORY
;
421 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
425 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
);
429 *ppv
= result
.Detach();
434 template<class T
, class T1
, class T2
, class T3
, class T4
, class R
>
435 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, REFIID riid
, R
** ppv
)
444 ATLTRY(obj
= new _CComObject
<T
>);
446 return E_OUTOFMEMORY
;
447 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
451 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
);
455 *ppv
= result
.Detach();
460 template<class T
, class T1
, class T2
, class T3
, class T4
, class T5
, class R
>
461 HRESULT
inline ShellObjectCreatorInit(T1 initArg1
, T2 initArg2
, T3 initArg3
, T4 initArg4
, T5 initArg5
, REFIID riid
, R
** ppv
)
470 ATLTRY(obj
= new _CComObject
<T
>);
472 return E_OUTOFMEMORY
;
473 hResult
= obj
->QueryInterface(riid
, reinterpret_cast<void **>(&result
));
477 hResult
= obj
->Initialize(initArg1
, initArg2
, initArg3
, initArg4
, initArg5
);
481 *ppv
= result
.Detach();
486 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, LPCSTR pstrValue
)
488 pStrRet
->uType
= STRRET_CSTR
;
489 strcpy(pStrRet
->cStr
, pstrValue
);
493 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, LPCWSTR pwstrValue
)
495 ULONG cchr
= wcslen(pwstrValue
);
496 LPWSTR buffer
= static_cast<LPWSTR
>(CoTaskMemAlloc((cchr
+ 1) * sizeof(WCHAR
)));
498 return E_OUTOFMEMORY
;
500 pStrRet
->uType
= STRRET_WSTR
;
501 pStrRet
->pOleStr
= buffer
;
502 wcscpy(buffer
, pwstrValue
);
506 HRESULT
inline SHSetStrRet(LPSTRRET pStrRet
, HINSTANCE hInstance
, DWORD resId
)
508 WCHAR Buffer
[MAX_PATH
];
510 if (!LoadStringW(hInstance
, resId
, Buffer
, MAX_PATH
))
513 return SHSetStrRet(pStrRet
, Buffer
);
516 #endif /* __cplusplus */
518 #endif /* __ROS_SHELL_UTILS_H */