1 // MyCom.h
2 
3 #ifndef __MYCOM_H
4 #define __MYCOM_H
5 
6 #include "MyWindows.h"
7 
8 #ifndef RINOK
9 #define RINOK(x) { HRESULT __result_ = (x); if (__result_ != S_OK) return __result_; }
10 #endif
11 
12 template <class T>
13 class CMyComPtr
14 {
15   T* _p;
16 public:
17   // typedef T _PtrClass;
CMyComPtr()18   CMyComPtr() { _p = NULL;}
CMyComPtr(T * p)19   CMyComPtr(T* p) {if ((_p = p) != NULL) p->AddRef(); }
CMyComPtr(const CMyComPtr<T> & lp)20   CMyComPtr(const CMyComPtr<T>& lp)
21   {
22     if ((_p = lp._p) != NULL)
23       _p->AddRef();
24   }
~CMyComPtr()25   ~CMyComPtr() { if (_p) _p->Release(); }
Release()26   void Release() { if (_p) { _p->Release(); _p = NULL; } }
27   operator T*() const {  return (T*)_p;  }
28   // T& operator*() const {  return *_p; }
29   T** operator&() { return &_p; }
30   T* operator->() const { return _p; }
31   T* operator=(T* p)
32   {
33     if (p != 0)
34       p->AddRef();
35     if (_p)
36       _p->Release();
37     _p = p;
38     return p;
39   }
40   T* operator=(const CMyComPtr<T>& lp) { return (*this = lp._p); }
41   bool operator!() const { return (_p == NULL); }
42   // bool operator==(T* pT) const {  return _p == pT; }
43   // Compare two objects for equivalence
Attach(T * p2)44   void Attach(T* p2)
45   {
46     Release();
47     _p = p2;
48   }
Detach()49   T* Detach()
50   {
51     T* pt = _p;
52     _p = NULL;
53     return pt;
54   }
55   #ifdef _WIN32
56   HRESULT CoCreateInstance(REFCLSID rclsid, REFIID iid, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
57   {
58     return ::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, (void**)&_p);
59   }
60   #endif
61   /*
62   HRESULT CoCreateInstance(LPCOLESTR szProgID, LPUNKNOWN pUnkOuter = NULL, DWORD dwClsContext = CLSCTX_ALL)
63   {
64     CLSID clsid;
65     HRESULT hr = CLSIDFromProgID(szProgID, &clsid);
66     ATLASSERT(_p == NULL);
67     if (SUCCEEDED(hr))
68       hr = ::CoCreateInstance(clsid, pUnkOuter, dwClsContext, __uuidof(T), (void**)&_p);
69     return hr;
70   }
71   */
72   template <class Q>
QueryInterface(REFGUID iid,Q ** pp)73   HRESULT QueryInterface(REFGUID iid, Q** pp) const
74   {
75     return _p->QueryInterface(iid, (void**)pp);
76   }
77 };
78 
79 //////////////////////////////////////////////////////////
80 
StringToBstr(LPCOLESTR src,BSTR * bstr)81 inline HRESULT StringToBstr(LPCOLESTR src, BSTR *bstr)
82 {
83   *bstr = ::SysAllocString(src);
84   return (*bstr != 0) ? S_OK : E_OUTOFMEMORY;
85 }
86 
87 class CMyComBSTR
88 {
89 public:
90   BSTR m_str;
CMyComBSTR()91   CMyComBSTR(): m_str(NULL) {}
CMyComBSTR(LPCOLESTR src)92   CMyComBSTR(LPCOLESTR src) { m_str = ::SysAllocString(src); }
93   // CMyComBSTR(int nSize) { m_str = ::SysAllocStringLen(NULL, nSize); }
94   // CMyComBSTR(int nSize, LPCOLESTR sz) { m_str = ::SysAllocStringLen(sz, nSize);  }
CMyComBSTR(const CMyComBSTR & src)95   CMyComBSTR(const CMyComBSTR& src) { m_str = src.MyCopy(); }
96   /*
97   CMyComBSTR(REFGUID src)
98   {
99     LPOLESTR szGuid;
100     StringFromCLSID(src, &szGuid);
101     m_str = ::SysAllocString(szGuid);
102     CoTaskMemFree(szGuid);
103   }
104   */
~CMyComBSTR()105   ~CMyComBSTR() { ::SysFreeString(m_str); }
106   CMyComBSTR& operator=(const CMyComBSTR& src)
107   {
108     if (m_str != src.m_str)
109     {
110       if (m_str)
111         ::SysFreeString(m_str);
112       m_str = src.MyCopy();
113     }
114     return *this;
115   }
116   CMyComBSTR& operator=(LPCOLESTR src)
117   {
118     ::SysFreeString(m_str);
119     m_str = ::SysAllocString(src);
120     return *this;
121   }
Length()122   unsigned int Length() const { return ::SysStringLen(m_str); }
BSTR()123   operator BSTR() const { return m_str; }
124   BSTR* operator&() { return &m_str; }
MyCopy()125   BSTR MyCopy() const
126   {
127     int byteLen = ::SysStringByteLen(m_str);
128     BSTR res = ::SysAllocStringByteLen(NULL, byteLen);
129     memcpy(res, m_str, byteLen);
130     return res;
131   }
132   /*
133   void Attach(BSTR src) { m_str = src; }
134   BSTR Detach()
135   {
136     BSTR s = m_str;
137     m_str = NULL;
138     return s;
139   }
140   */
Empty()141   void Empty()
142   {
143     ::SysFreeString(m_str);
144     m_str = NULL;
145   }
146   bool operator!() const {  return (m_str == NULL); }
147 };
148 
149 //////////////////////////////////////////////////////////
150 
151 class CMyUnknownImp
152 {
153 public:
154   ULONG __m_RefCount;
CMyUnknownImp()155   CMyUnknownImp(): __m_RefCount(0) {}
156 };
157 
158 #define MY_QUERYINTERFACE_BEGIN STDMETHOD(QueryInterface) \
159     (REFGUID iid, void **outObject) {
160 
161 #define MY_QUERYINTERFACE_ENTRY(i) if (iid == IID_ ## i) \
162     { *outObject = (void *)(i *)this; AddRef(); return S_OK; }
163 
164 #define MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) if (iid == IID_IUnknown) \
165     { *outObject = (void *)(IUnknown *)(i *)this; AddRef(); return S_OK; }
166 
167 #define MY_QUERYINTERFACE_BEGIN2(i) MY_QUERYINTERFACE_BEGIN \
168     MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
169     MY_QUERYINTERFACE_ENTRY(i)
170 
171 #define MY_QUERYINTERFACE_END return E_NOINTERFACE; }
172 
173 #define MY_ADDREF_RELEASE \
174 STDMETHOD_(ULONG, AddRef)() { return ++__m_RefCount; } \
175 STDMETHOD_(ULONG, Release)() { if (--__m_RefCount != 0)  \
176   return __m_RefCount; delete this; return 0; }
177 
178 #define MY_UNKNOWN_IMP_SPEC(i) \
179   MY_QUERYINTERFACE_BEGIN \
180   i \
181   MY_QUERYINTERFACE_END \
182   MY_ADDREF_RELEASE
183 
184 
185 #define MY_UNKNOWN_IMP MY_QUERYINTERFACE_BEGIN \
186   MY_QUERYINTERFACE_ENTRY_UNKNOWN(IUnknown) \
187   MY_QUERYINTERFACE_END \
188   MY_ADDREF_RELEASE
189 
190 #define MY_UNKNOWN_IMP1(i) MY_UNKNOWN_IMP_SPEC( \
191   MY_QUERYINTERFACE_ENTRY_UNKNOWN(i) \
192   MY_QUERYINTERFACE_ENTRY(i) \
193   )
194 
195 #define MY_UNKNOWN_IMP2(i1, i2) MY_UNKNOWN_IMP_SPEC( \
196   MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
197   MY_QUERYINTERFACE_ENTRY(i1) \
198   MY_QUERYINTERFACE_ENTRY(i2) \
199   )
200 
201 #define MY_UNKNOWN_IMP3(i1, i2, i3) MY_UNKNOWN_IMP_SPEC( \
202   MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
203   MY_QUERYINTERFACE_ENTRY(i1) \
204   MY_QUERYINTERFACE_ENTRY(i2) \
205   MY_QUERYINTERFACE_ENTRY(i3) \
206   )
207 
208 #define MY_UNKNOWN_IMP4(i1, i2, i3, i4) MY_UNKNOWN_IMP_SPEC( \
209   MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
210   MY_QUERYINTERFACE_ENTRY(i1) \
211   MY_QUERYINTERFACE_ENTRY(i2) \
212   MY_QUERYINTERFACE_ENTRY(i3) \
213   MY_QUERYINTERFACE_ENTRY(i4) \
214   )
215 
216 #define MY_UNKNOWN_IMP5(i1, i2, i3, i4, i5) MY_UNKNOWN_IMP_SPEC( \
217   MY_QUERYINTERFACE_ENTRY_UNKNOWN(i1) \
218   MY_QUERYINTERFACE_ENTRY(i1) \
219   MY_QUERYINTERFACE_ENTRY(i2) \
220   MY_QUERYINTERFACE_ENTRY(i3) \
221   MY_QUERYINTERFACE_ENTRY(i4) \
222   MY_QUERYINTERFACE_ENTRY(i5) \
223   )
224 
225 #endif
226