soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SComCli.h
1// This is a part of the Active Template Library.
2// Copyright (C) Microsoft Corporation
3// All rights reserved.
4//
5// This source code is only intended as a supplement to the
6// Active Template Library Reference and related
7// electronic documentation provided with the library.
8// See these sources for detailed information regarding the
9// Active Template Library product.
10
11#ifndef __SCOMCLI_H__
12#define __SCOMCLI_H__
13
14#include <sdef.h>
15#include <windows.h>
16#include <unknwn.h>
17#include <oaidl.h>
18
19#ifndef SASSERT
20#include <assert.h>
21#define SASSERT(x) assert(x);
22#endif
23
24#pragma warning (push)
25#pragma warning (disable: 4127) // conditional expression constant
26#pragma warning (disable: 4571) //catch(...) blocks compiled with /EHs do NOT catch or re-throw Structured Exceptions
27
28
29#pragma pack(push,8)
30SNSBEGIN
31
32/////////////////////////////////////////////////////////////////////////////
33// Smart Pointer helpers
34
35
36inline IUnknown* SComPtrAssign(IUnknown** pp, IUnknown* lp)
37{
38 if (pp == NULL)
39 return NULL;
40
41 if (lp != NULL)
42 lp->AddRef();
43 if (*pp)
44 (*pp)->Release();
45 *pp = lp;
46 return lp;
47}
48
49inline IUnknown* SComQIPtrAssign(IUnknown** pp, IUnknown* lp, REFIID riid)
50{
51 if (pp == NULL)
52 return NULL;
53
54 IUnknown* pTemp = *pp;
55 *pp = NULL;
56 if (lp != NULL)
57 lp->QueryInterface(riid, (void**)pp);
58 if (pTemp)
59 pTemp->Release();
60 return *pp;
61}
62
63
64/////////////////////////////////////////////////////////////////////////////
65// COM Smart pointers
66
67template <class T>
68class _SNoAddRefReleaseOnCComPtr : public T
69{
70 private:
71 STDMETHOD_(ULONG, AddRef)()=0;
72 STDMETHOD_(ULONG, Release)()=0;
73};
74
75//SComPtrBase provides the basis for all other smart pointers
76//The other smartpointers add their own constructors and operators
77template <class T>
78class SComPtrBase
79{
80protected:
81 SComPtrBase() throw()
82 {
83 p = NULL;
84 }
85 SComPtrBase( int nNull) throw()
86 {
87 SASSERT(nNull == 0);
88 (void)nNull;
89 p = NULL;
90 }
91 SComPtrBase( T* lp, BOOL bAddRef) throw()
92 {
93 p = lp;
94 if (p != NULL && bAddRef)
95 p->AddRef();
96 }
97public:
98 typedef T _PtrClass;
99 ~SComPtrBase()
100 {
101 if (p)
102 p->Release();
103 }
104 operator T*() const throw()
105 {
106 return p;
107 }
108 T& operator*() const
109 {
110 SASSERT(p!=NULL);
111 return *p;
112 }
113 //The assert on operator& usually indicates a bug. If this is really
114 //what is needed, however, take the address of the p member explicitly.
115 T** operator&() throw()
116 {
117 SASSERT(p==NULL);
118 return &p;
119 }
120 _SNoAddRefReleaseOnCComPtr<T>* operator->() const throw()
121 {
122 SASSERT(p!=NULL);
123 return (_SNoAddRefReleaseOnCComPtr<T>*)p;
124 }
125 bool operator!() const throw()
126 {
127 return (p == NULL);
128 }
129 bool operator<( T* pT) const throw()
130 {
131 return p < pT;
132 }
133 bool operator!=( T* pT) const
134 {
135 return !operator==(pT);
136 }
137 bool operator==( T* pT) const throw()
138 {
139 return p == pT;
140 }
141
142 // Release the interface and set to NULL
143 void Release() throw()
144 {
145 T* pTemp = p;
146 if (pTemp)
147 {
148 p = NULL;
149 pTemp->Release();
150 }
151 }
152 // Compare two objects for equivalence
153 bool IsEqualObject( IUnknown* pOther) throw()
154 {
155 if (p == NULL && pOther == NULL)
156 return true; // They are both NULL objects
157
158 if (p == NULL || pOther == NULL)
159 return false; // One is NULL the other is not
160
161 IUnknown* punk1;
162 IUnknown* punk2;
163 p->QueryInterface(__uuidof(IUnknown), (void**)&punk1);
164 pOther->QueryInterface(__uuidof(IUnknown), (void**)&punk2);
165 bool bEqual = punk1 == punk2;
166 punk1->Release();
167 punk2->Release();
168 return bEqual;
169 }
170 // Attach to an existing interface (does not AddRef)
171 void Attach( T* p2) throw()
172 {
173 if (p)
174 p->Release();
175 p = p2;
176 }
177 // Detach the interface (does not Release)
178 T* Detach() throw()
179 {
180 T* pt = p;
181 p = NULL;
182 return pt;
183 }
184 HRESULT CopyTo( T** ppT) throw()
185 {
186 SASSERT(ppT != NULL);
187 if (ppT == NULL)
188 return E_POINTER;
189 *ppT = p;
190 if (p)
191 p->AddRef();
192 return S_OK;
193 }
194 HRESULT CoCreateInstance( REFCLSID rclsid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
195 {
196 SASSERT(p == NULL);
197 return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
198 }
199 HRESULT CoCreateInstance( LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL) throw()
200 {
201 CLSID clsid;
202 HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
203 SASSERT(p == NULL);
204 if (SUCCEEDED(hr))
205 hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&p);
206 return hr;
207 }
208 template <class Q>
209 HRESULT QueryInterface( Q** pp) const throw()
210 {
211 SASSERT(pp != NULL);
212 return p->QueryInterface(__uuidof(Q), (void**)pp);
213 }
214 T* p;
215};
216
217template <class T>
218class SComPtr : public SComPtrBase<T>
219{
220public:
221 SComPtr() throw()
222 {
223 }
224 SComPtr(int nNull) throw() :
225 SComPtrBase<T>(nNull)
226 {
227 }
228 SComPtr(T* lp, BOOL bAddRef = TRUE) throw() :
229 SComPtrBase<T>(lp,bAddRef)
230
231 {
232 }
233 SComPtr( const SComPtr<T>& lp) throw() :
234 SComPtrBase<T>(lp.p,TRUE)
235 {
236 }
237 T* operator=( T* lp) throw()
238 {
239 if(*this!=lp)
240 {
241 return static_cast<T*>(SComPtrAssign((IUnknown**)&this->p, lp));
242 }
243 return *this;
244 }
245 template <typename Q>
246 T* operator=( const SComPtr<Q>& lp) throw()
247 {
248 if( !SComPtrBase<T>::IsEqualObject(lp) )
249 {
250 return static_cast<T*>(SComQIPtrAssign((IUnknown**)&this->p, lp, __uuidof(T)));
251 }
252 return *this;
253 }
254 T* operator=( const SComPtr<T>& lp) throw()
255 {
256 if(*this!=lp)
257 {
258 return static_cast<T*>(SComPtrAssign((IUnknown**)&this->p, lp));
259 }
260 return *this;
261 }
262};
263
264//specialization for IDispatch
265template <>
266class SComPtr<IDispatch> : public SComPtrBase<IDispatch>
267{
268public:
269 SComPtr() throw()
270 {
271 }
272 SComPtr(IDispatch* lp, BOOL bAddRef = TRUE) throw() :
273 SComPtrBase<IDispatch>(lp,bAddRef)
274 {
275 }
276 SComPtr(const SComPtr<IDispatch>& lp) throw() :
277 SComPtrBase<IDispatch>(lp.p,TRUE)
278 {
279 }
280 IDispatch* operator=(IDispatch* lp) throw()
281 {
282 if(*this!=lp)
283 {
284 return static_cast<IDispatch*>(SComPtrAssign((IUnknown**)&p, lp));
285 }
286 return *this;
287 }
288 IDispatch* operator=(const SComPtr<IDispatch>& lp) throw()
289 {
290 if(*this!=lp)
291 {
292 return static_cast<IDispatch*>(SComPtrAssign((IUnknown**)&p, lp.p));
293 }
294 return *this;
295 }
296
297// IDispatch specific stuff
298 HRESULT GetPropertyByName( LPCOLESTR lpsz, VARIANT* pVar) throw()
299 {
300 SASSERT(p);
301 SASSERT(pVar);
302 DISPID dwDispID;
303 HRESULT hr = GetIDOfName(lpsz, &dwDispID);
304 if (SUCCEEDED(hr))
305 hr = GetProperty(dwDispID, pVar);
306 return hr;
307 }
308 HRESULT GetProperty( DISPID dwDispID, VARIANT* pVar) throw()
309 {
310 return GetProperty(p, dwDispID, pVar);
311 }
312 HRESULT PutPropertyByName( LPCOLESTR lpsz, VARIANT* pVar) throw()
313 {
314 SASSERT(p);
315 SASSERT(pVar);
316 DISPID dwDispID;
317 HRESULT hr = GetIDOfName(lpsz, &dwDispID);
318 if (SUCCEEDED(hr))
319 hr = PutProperty(dwDispID, pVar);
320 return hr;
321 }
322 HRESULT PutProperty( DISPID dwDispID, VARIANT* pVar) throw()
323 {
324 return PutProperty(p, dwDispID, pVar);
325 }
326 HRESULT GetIDOfName( LPCOLESTR lpsz, DISPID* pdispid) throw()
327 {
328 return p->GetIDsOfNames(IID_NULL, const_cast<LPOLESTR*>(&lpsz), 1, LOCALE_USER_DEFAULT, pdispid);
329 }
330 // Invoke a method by DISPID with no parameters
331 HRESULT Invoke0( DISPID dispid, VARIANT* pvarRet = NULL) throw()
332 {
333 DISPPARAMS dispparams = { NULL, NULL, 0, 0};
334 return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
335 }
336 // Invoke a method by name with no parameters
337 HRESULT Invoke0( LPCOLESTR lpszName, VARIANT* pvarRet = NULL) throw()
338 {
339 HRESULT hr;
340 DISPID dispid;
341 hr = GetIDOfName(lpszName, &dispid);
342 if (SUCCEEDED(hr))
343 hr = Invoke0(dispid, pvarRet);
344 return hr;
345 }
346 // Invoke a method by DISPID with a single parameter
347 HRESULT Invoke1( DISPID dispid, VARIANT* pvarParam1, VARIANT* pvarRet = NULL) throw()
348 {
349 DISPPARAMS dispparams = { pvarParam1, NULL, 1, 0};
350 return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
351 }
352 // Invoke a method by name with a single parameter
353 HRESULT Invoke1( LPCOLESTR lpszName, VARIANT* pvarParam1, VARIANT* pvarRet = NULL) throw()
354 {
355 HRESULT hr;
356 DISPID dispid;
357 hr = GetIDOfName(lpszName, &dispid);
358 if (SUCCEEDED(hr))
359 hr = Invoke1(dispid, pvarParam1, pvarRet);
360 return hr;
361 }
362 // Invoke a method by DISPID with two parameters
363 HRESULT Invoke2( DISPID dispid, VARIANT* pvarParam1, VARIANT* pvarParam2, VARIANT* pvarRet = NULL) throw();
364 // Invoke a method by name with two parameters
365 HRESULT Invoke2( LPCOLESTR lpszName, VARIANT* pvarParam1, VARIANT* pvarParam2, VARIANT* pvarRet = NULL) throw()
366 {
367 HRESULT hr;
368 DISPID dispid;
369 hr = GetIDOfName(lpszName, &dispid);
370 if (SUCCEEDED(hr))
371 hr = Invoke2(dispid, pvarParam1, pvarParam2, pvarRet);
372 return hr;
373 }
374 // Invoke a method by DISPID with N parameters
375 HRESULT InvokeN(DISPID dispid, VARIANT* pvarParams, int nParams, VARIANT* pvarRet = NULL) throw()
376 {
377 DISPPARAMS dispparams = { pvarParams, NULL, (UINT)nParams, 0};
378 return p->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, pvarRet, NULL, NULL);
379 }
380 // Invoke a method by name with Nparameters
381 HRESULT InvokeN(LPCOLESTR lpszName, VARIANT* pvarParams, int nParams, VARIANT* pvarRet = NULL) throw()
382 {
383 HRESULT hr;
384 DISPID dispid;
385 hr = GetIDOfName(lpszName, &dispid);
386 if (SUCCEEDED(hr))
387 hr = InvokeN(dispid, pvarParams, nParams, pvarRet);
388 return hr;
389 }
390 static HRESULT PutProperty( IDispatch* p, DISPID dwDispID, VARIANT* pVar) throw()
391 {
392 SASSERT(p);
393 SASSERT(pVar != NULL);
394 if (pVar == NULL)
395 return E_POINTER;
396
397 if(p == NULL)
398 return E_INVALIDARG;
399
400 DISPPARAMS dispparams = {NULL, NULL, 1, 1};
401 dispparams.rgvarg = pVar;
402 DISPID dispidPut = DISPID_PROPERTYPUT;
403 dispparams.rgdispidNamedArgs = &dispidPut;
404
405 if (pVar->vt == VT_UNKNOWN || pVar->vt == VT_DISPATCH ||
406 (pVar->vt & VT_ARRAY) || (pVar->vt & VT_BYREF))
407 {
408 HRESULT hr = p->Invoke(dwDispID, IID_NULL,
409 LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUTREF,
410 &dispparams, NULL, NULL, NULL);
411 if (SUCCEEDED(hr))
412 return hr;
413 }
414 return p->Invoke(dwDispID, IID_NULL,
415 LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT,
416 &dispparams, NULL, NULL, NULL);
417 }
418 static HRESULT GetProperty( IDispatch* p, DISPID dwDispID, VARIANT* pVar) throw()
419 {
420 SASSERT(p);
421 SASSERT(pVar != NULL);
422 if (pVar == NULL)
423 return E_POINTER;
424
425 if(p == NULL)
426 return E_INVALIDARG;
427
428 DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
429 return p->Invoke(dwDispID, IID_NULL,
430 LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
431 &dispparamsNoArgs, pVar, NULL, NULL);
432 }
433};
434
435template <class T, const IID* piid = &__uuidof(T)>
436class SComQIPtr : public SComPtr<T>
437{
438public:
439 SComQIPtr() throw()
440 {
441 }
442 SComQIPtr( T* lp, BOOL bAddRef = TRUE) throw() :
443 SComPtr<T>(lp,bAddRef)
444 {
445 }
446 SComQIPtr( const SComQIPtr<T,piid>& lp) throw() :
447 SComPtr<T>(lp.p)
448 {
449 }
450 SComQIPtr( IUnknown* lp) throw()
451 {
452 if (lp != NULL)
453 lp->QueryInterface(*piid, (void **)&this->p);
454 }
455 T* operator=( T* lp) throw()
456 {
457 if(*this!=lp)
458 {
459 return static_cast<T*>(SComPtrAssign((IUnknown**)&this->p, lp));
460 }
461 return *this;
462 }
463 T* operator=( const SComQIPtr<T,piid>& lp) throw()
464 {
465 if(*this!=lp)
466 {
467 return static_cast<T*>(SComPtrAssign((IUnknown**)&this->p, lp.p));
468 }
469 return *this;
470 }
471 T* operator=( IUnknown* lp) throw()
472 {
473 if(*this!=lp)
474 {
475 return static_cast<T*>(SComQIPtrAssign((IUnknown**)&this->p, lp, *piid));
476 }
477 return *this;
478 }
479};
480
481//Specialization to make it work
482template<>
483class SComQIPtr<IUnknown, &IID_IUnknown> : public SComPtr<IUnknown>
484{
485public:
486 SComQIPtr() throw()
487 {
488 }
489 SComQIPtr( IUnknown* lp) throw()
490 {
491 //Actually do a QI to get identity
492 if (lp != NULL)
493 lp->QueryInterface(__uuidof(IUnknown), (void **)&p);
494 }
495 SComQIPtr( const SComQIPtr<IUnknown,&IID_IUnknown>& lp) throw() :
496 SComPtr<IUnknown>(lp.p)
497 {
498 }
499 IUnknown* operator=( IUnknown* lp) throw()
500 {
501 if(*this!=lp)
502 {
503 //Actually do a QI to get identity
504 return SComQIPtrAssign((IUnknown**)&p, lp, __uuidof(IUnknown));
505 }
506 return *this;
507 }
508
509 IUnknown* operator=( const SComQIPtr<IUnknown,&IID_IUnknown>& lp) throw()
510 {
511 if(*this!=lp)
512 {
513 return SComPtrAssign((IUnknown**)&p, lp.p);
514 }
515 return *this;
516 }
517};
518
519typedef SComQIPtr<IDispatch, &IID_IDispatch> CComDispatchDriver;
520
521SNSEND
522#pragma pack(pop)
523
524#pragma warning (pop)
525
526
527#endif // __SCOMCLI_H__