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