My Project
combase.h
1 //------------------------------------------------------------------------------
2 // File: ComBase.h
3 //
4 // Desc: DirectShow base classes - defines a class hierarchy for creating
5 // COM objects.
6 //
7 // Copyright (c) Microsoft Corporation. All rights reserved.
8 //------------------------------------------------------------------------------
9 
10 
11 /*
12 
13 a. Derive your COM object from CUnknown
14 
15 b. Make a static CreateInstance function that takes an LPUNKNOWN, an HRESULT *
16  and a TCHAR *. The LPUNKNOWN defines the object to delegate IUnknown calls
17  to. The HRESULT * allows error codes to be passed around constructors and
18  the TCHAR * is a descriptive name that can be printed on the debugger.
19 
20  It is important that constructors only change the HRESULT * if they have
21  to set an ERROR code, if it was successful then leave it alone or you may
22  overwrite an error code from an object previously created.
23 
24  When you call a constructor the descriptive name should be in static store
25  as we do not copy the string. To stop large amounts of memory being used
26  in retail builds by all these static strings use the NAME macro,
27 
28  CMyFilter = new CImplFilter(NAME("My filter"),pUnknown,phr);
29  if (FAILED(hr)) {
30  return hr;
31  }
32 
33  In retail builds NAME(_x_) compiles to NULL, the base CBaseObject class
34  knows not to do anything with objects that don't have a name.
35 
36 c. Have a constructor for your object that passes the LPUNKNOWN, HRESULT * and
37  TCHAR * to the CUnknown constructor. You can set the HRESULT if you have an
38  error, or just simply pass it through to the constructor.
39 
40  The object creation will fail in the class factory if the HRESULT indicates
41  an error (ie FAILED(HRESULT) == TRUE)
42 
43 d. Create a FactoryTemplate with your object's class id and CreateInstance
44  function.
45 
46 Then (for each interface) either
47 
48 Multiple inheritance
49 
50 1. Also derive it from ISomeInterface
51 2. Include DECLARE_IUNKNOWN in your class definition to declare
52  implementations of QueryInterface, AddRef and Release that
53  call the outer unknown
54 3. Override NonDelegatingQueryInterface to expose ISomeInterface by
55  code something like
56 
57  if (riid == IID_ISomeInterface) {
58  return GetInterface((ISomeInterface *) this, ppv);
59  } else {
60  return CUnknown::NonDelegatingQueryInterface(riid, ppv);
61  }
62 
63 4. Declare and implement the member functions of ISomeInterface.
64 
65 or: Nested interfaces
66 
67 1. Declare a class derived from CUnknown
68 2. Include DECLARE_IUNKNOWN in your class definition
69 3. Override NonDelegatingQueryInterface to expose ISomeInterface by
70  code something like
71 
72  if (riid == IID_ISomeInterface) {
73  return GetInterface((ISomeInterface *) this, ppv);
74  } else {
75  return CUnknown::NonDelegatingQueryInterface(riid, ppv);
76  }
77 
78 4. Implement the member functions of ISomeInterface. Use GetOwner() to
79  access the COM object class.
80 
81 And in your COM object class:
82 
83 5. Make the nested class a friend of the COM object class, and declare
84  an instance of the nested class as a member of the COM object class.
85 
86  NOTE that because you must always pass the outer unknown and an hResult
87  to the CUnknown constructor you cannot use a default constructor, in
88  other words you will have to make the member variable a pointer to the
89  class and make a NEW call in your constructor to actually create it.
90 
91 6. override the NonDelegatingQueryInterface with code like this:
92 
93  if (riid == IID_ISomeInterface) {
94  return m_pImplFilter->
95  NonDelegatingQueryInterface(IID_ISomeInterface, ppv);
96  } else {
97  return CUnknown::NonDelegatingQueryInterface(riid, ppv);
98  }
99 
100 You can have mixed classes which support some interfaces via multiple
101 inheritance and some via nested classes
102 
103 */
104 #pragma once
105 
106 #ifndef __COMBASE__
107 #define __COMBASE__
108 
109 // Filter Setup data structures no defined in axextend.idl
110 
111 typedef REGPINTYPES
112 AMOVIESETUP_MEDIATYPE, * PAMOVIESETUP_MEDIATYPE, * FAR LPAMOVIESETUP_MEDIATYPE;
113 
114 typedef REGFILTERPINS
115 AMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * FAR LPAMOVIESETUP_PIN;
116 
117 typedef struct _AMOVIESETUP_FILTER
118 {
119  const CLSID * clsID;
120  const WCHAR * strName;
121  DWORD dwMerit;
122  UINT nPins;
123  const AMOVIESETUP_PIN * lpPin;
124 }
126 
127 /* The DLLENTRY module initialises the module handle on loading */
128 
129 extern HINSTANCE g_hInst;
130 
131 /* On DLL load remember which platform we are running on */
132 
133 extern DWORD g_amPlatform;
134 extern OSVERSIONINFO g_osInfo; // Filled in by GetVersionEx
135 
136 /* Version of IUnknown that is renamed to allow a class to support both
137  non delegating and delegating IUnknowns in the same COM object */
138 
139 #ifndef INONDELEGATINGUNKNOWN_DEFINED
140 DECLARE_INTERFACE(INonDelegatingUnknown)
141 {
142  STDMETHOD(NonDelegatingQueryInterface) (THIS_ REFIID, LPVOID *) PURE;
143  STDMETHOD_(ULONG, NonDelegatingAddRef)(THIS) PURE;
144  STDMETHOD_(ULONG, NonDelegatingRelease)(THIS) PURE;
145 };
146 #define INONDELEGATINGUNKNOWN_DEFINED
147 #endif
148 
149 typedef INonDelegatingUnknown *PNDUNKNOWN;
150 
151 
152 /* This is the base object class that supports active object counting. As
153  part of the debug facilities we trace every time a C++ object is created
154  or destroyed. The name of the object has to be passed up through the class
155  derivation list during construction as you cannot call virtual functions
156  in the constructor. The downside of all this is that every single object
157  constructor has to take an object name parameter that describes it */
158 
160 {
161 
162 private:
163 
164  // Disable the copy constructor and assignment by default so you will get
165  // compiler errors instead of unexpected behaviour if you pass objects
166  // by value or assign objects.
167  CBaseObject(const CBaseObject& objectSrc); // no implementation
168  void operator=(const CBaseObject& objectSrc); // no implementation
169 
170 private:
171  static LONG m_cObjects; /* Total number of objects active */
172 
173 protected:
174 #ifdef DEBUG
175  DWORD m_dwCookie; /* Cookie identifying this object */
176 #endif
177 
178 
179 public:
180 
181  /* These increment and decrement the number of active objects */
182 
183  CBaseObject(const TCHAR *pName);
184 #ifdef UNICODE
185  CBaseObject(const char *pName);
186 #endif
187  ~CBaseObject();
188 
189  /* Call this to find if there are any CUnknown derived objects active */
190 
191  static LONG ObjectsActive() {
192  return m_cObjects;
193  };
194 };
195 
196 
197 /* An object that supports one or more COM interfaces will be based on
198  this class. It supports counting of total objects for DLLCanUnloadNow
199  support, and an implementation of the core non delegating IUnknown */
200 
201 class AM_NOVTABLE CUnknown : public INonDelegatingUnknown,
202  public CBaseObject
203 {
204 private:
205  const LPUNKNOWN m_pUnknown; /* Owner of this object */
206 
207 protected: /* So we can override NonDelegatingRelease() */
208  volatile LONG m_cRef; /* Number of reference counts */
209 
210 public:
211 
212  CUnknown(const TCHAR *pName, LPUNKNOWN pUnk);
213  virtual ~CUnknown() {};
214 
215  // This is redundant, just use the other constructor
216  // as we never touch the HRESULT in this anyway
217  CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr);
218 #ifdef UNICODE
219  CUnknown(const char *pName, LPUNKNOWN pUnk);
220  CUnknown(char *pName, LPUNKNOWN pUnk,HRESULT *phr);
221 #endif
222 
223  /* Return the owner of this object */
224 
225  LPUNKNOWN GetOwner() const {
226  return m_pUnknown;
227  };
228 
229  /* Called from the class factory to create a new instance, it is
230  pure virtual so it must be overriden in your derived class */
231 
232  /* static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *) */
233 
234  /* Non delegating unknown implementation */
235 
236  STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **);
237  STDMETHODIMP_(ULONG) NonDelegatingAddRef();
238  STDMETHODIMP_(ULONG) NonDelegatingRelease();
239 };
240 
241 #if (_MSC_VER <= 1200)
242 #pragma warning(disable:4211)
243 
244 /* The standard InterlockedXXX functions won't take volatiles */
245 static inline LONG WINAPI InterlockedIncrement( volatile LONG * plong )
246 { return InterlockedIncrement( const_cast<LONG*>( plong ) ); }
247 
248 static inline LONG WINAPI InterlockedDecrement( volatile LONG * plong )
249 { return InterlockedDecrement( const_cast<LONG*>( plong ) ); }
250 
251 #pragma warning(default:4211)
252 #endif
253 
254 
255 /* Return an interface pointer to a requesting client
256  performing a thread safe AddRef as necessary */
257 
258 STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv);
259 
260 /* A function that can create a new COM object */
261 
262 typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr);
263 
264 /* A function (can be NULL) which is called from the DLL entrypoint
265  routine for each factory template:
266 
267  bLoading - TRUE on DLL load, FALSE on DLL unload
268  rclsid - the m_ClsID of the entry
269 */
270 typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid);
271 
272 /* Create one of these per object class in an array so that
273  the default class factory code can create new instances */
274 
276 
277 public:
278 
279  const WCHAR * m_Name;
280  const CLSID * m_ClsID;
281  LPFNNewCOMObject m_lpfnNew;
282  LPFNInitRoutine m_lpfnInit;
283  const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter;
284 
285  BOOL IsClassID(REFCLSID rclsid) const {
286  return (IsEqualCLSID(*m_ClsID,rclsid));
287  };
288 
289  CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) const {
290  CheckPointer(phr,NULL);
291  return m_lpfnNew(pUnk, phr);
292  };
293 };
294 
295 
296 /* You must override the (pure virtual) NonDelegatingQueryInterface to return
297  interface pointers (using GetInterface) to the interfaces your derived
298  class supports (the default implementation only supports IUnknown) */
299 
300 #define DECLARE_IUNKNOWN \
301  STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \
302  return GetOwner()->QueryInterface(riid,ppv); \
303  }; \
304  STDMETHODIMP_(ULONG) AddRef() { \
305  return GetOwner()->AddRef(); \
306  }; \
307  STDMETHODIMP_(ULONG) Release() { \
308  return GetOwner()->Release(); \
309  };
310 
311 
312 
313 HINSTANCE LoadOLEAut32();
314 
315 
316 #endif /* __COMBASE__ */
317 
318 
319 
320 
Definition: combase.h:201
Definition: combase.h:159
Definition: combase.h:117
Definition: combase.h:275