CUnknown Class

CUnknown class hierarchy

All Microsoft® DirectShow® Component Object Model (COM) objects derive from the CUnknown abstract base class. This class facilitates the creation of simple COM objects that you can combine with other COM objects to support multiple interfaces. To use this class, derive your object from CUnknown and call the DECLARE_IUNKNOWN macro in the public section of your object class definition; this implements the IUnknown interface for your object. Note that if you derive from an object that has already done this, such as CBaseFilter, you do not need to do it yourself.

The CUnknown class supports only one interface, IUnknown. To support interfaces in addition to those provided by the base class, override the NonDelegatingQueryInterface method. In the overriding function, call the GetInterface function to retrieve the interface pointer for any interfaces your object supports. If the derived class does not implement the specified interface, you must query the base class to retrieve the interface.

For example, CBaseFilter supports the following interfaces directly.

CBaseFilter also supports IUnknown by passing queries for this interface to CUnknown. The following code sample demonstrates this process.

/* Override this to say what interfaces are supported and where */

STDMETHODIMP CBaseFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
    CheckPointer(ppv,E_POINTER);
    ValidateReadWritePtr(ppv,sizeof(PVOID));

    /* Do we have this interface */

    if (riid == IID_IFilter) {
         return GetInterface((IBaseFilter *) this, ppv);
    } else if (riid == IID_IMediaFilter) {
                   return GetInterface((IMediaFilter *) this, ppv);
    } else if (riid == IID_IPersist) {
                   return GetInterface((IPersist *) this, ppv);
    } else if (riid == IID_IAMovieSetup) {
                   return GetInterface((IAMovieSetup *) this, ppv);
    } else {
                   return CUnknown::NonDelegatingQueryInterface(riid, ppv);
    }
}

To build composite objects, the CUnknown constructor has an LPUNKNOWN parameter that is a pointer to the top-level IUnknown interface for the entire composite object (the object that includes all objects based on a class derived from CUnknown). If this value is non-NULL, CUnknown stores a pointer to the topmost object; if it is null, the topmost object is CUnknown itself. This way, the topmost object's IUnknown has the same implementation as the INonDelegatingUnknown interface.

A derived class will typically override the NonDelegatingQueryInterface method to return interfaces that it supports; however, it must delegate support for IUnknown to the CUnknown class implementation. Usually NonDelegatingAddRef and NonDelegatingRelease do not need to be overridden because the reference count for the whole object is managed inside the top-level object. However, NonDelegatingRelease might need to be overridden sometimes because its default action when the reference count goes to zero is to delete the object from inside itself.

CUnknown provides the CUnknown::GetOwner member function. GetOwner simply returns an LPUNKNOWN pointer to the controlling unknown. This is used in the DECLARE_IUNKNOWN macro when calling QueryInterface. It can also be used when creating a composite object to pass an LPUNKNOWN pointer to a component interface as an (equivalent) alternative to passing the LPUNKNOWN pointer that was passed to the composite object constructor.

When QueryInterface is called on an interface owned by a component interface, it is immediately passed to the NonDelegatingQueryInterface method of the top-level object's INonDelegatingUnknown::NonDelegatingQueryInterface method, which either returns an interface it implements itself or passes the call to the correct member or base class's INonDelegatingUnknown::NonDelegatingQueryInterface method. This then repeats the process until a component is found that implements the interface or calls CUnknown::NonDelegatingQueryInterface, which fails the call.

Note that the top-level object's CUnknown::NonDelegatingQueryInterface member function (as distinct from its own implementation) must be called to support IUnknown.

This design makes support for COM aggregation straightforward. The derived object's CreateInstance member function, which is called from the class factory (by CClassFactory::CreateInstance) passes the outer unknown (the pUnkOuter parameter from CoCreateInstance) on to CUnknown by calling the class constructor. So the object behaves as if it were part of a larger object by delegating its QueryInterface calls to the outer unknown.

Protected Data Members

m_cRef Number of reference counts (so the INonDelegatingUnknown::NonDelegatingRelease method can be overridden).

Member Functions

CUnknown Constructs a CUnknown object.
GetOwner Returns an LPUNKNOWN pointer to the controlling unknown.

Implemented INonDelegatingUnknown Methods

NonDelegatingAddRef Increments the reference count for an interface.
NonDelegatingQueryInterface Retrieves an interface and increments the reference count.
NonDelegatingRelease Decrements the reference count for an interface.

CUnknown::CUnknown

CUnknown Class

Constructs a CUnknown object.

Syntax

CUnknown(
    const TCHAR *pName,
    LPUNKNOWN pUnk
    );

Parameters

pName
Pointer to the name of the object used in the CBaseObject constructor for debugging purposes.
pUnk
Pointer to the owner of this object. If non-NULL, IUnknown calls are delegated to this object.

Return Value

No return value.

Remarks

The object is initialized with a reference count of zero. This reference count can be incremented when the object is queried for its first interface, depending on whether the object is currently being aggregated.

CUnknown::GetOwner

CUnknown Class

Retrieves this object's Component Object Model (COM) class owner.

Syntax

LPUNKNOWN GetOwner(void);

Return Value

Returns an LPUNKNOWN pointer to the controlling IUnknown interface.

CUnknown::NonDelegatingAddRef

CUnknown Class

Increments the reference count for an interface.

Syntax

ULONG NonDelegatingAddRef(void);

Return Value

Returns the reference count of the object.

Remarks

This member function provides a base class implementation of the INonDelegatingUnknown::NonDelegatingAddRef method. When the object derived from CUnknown is part of an aggregated object, this reference count modification is private to the embedded object.

CUnknown::NonDelegatingQueryInterface

CUnknown Class

Retrieves an interface and increments the reference count.

Syntax

HRESULT NonDelegatingQueryInterface(
    REFIID riid,
    void **ppv
    );

Parameters

riid
Reference identifier.
ppv
Address of a pointer to the interface.

Return Value

Returns E_POINTER if ppv is invalid. Returns NOERROR if the query is successful or E_NOINTERFACE if it is not.

Remarks

This member function provides a base class implementation of the INonDelegatingUnknown::NonDelegatingQueryInterface method. Override this class to return interfaces on the object in the derived class.

CUnknown::NonDelegatingRelease

CUnknown Class

Decrements the reference count for an interface.

Syntax

ULONG NonDelegatingRelease(void);

Return Value

Returns the reference count.

Remarks

This member function provides a base class implementation of the INonDelegatingUnknown::NonDelegatingRelease method. When the object derived from CUnknown is part of an aggregated object, this reference count modification is private to the embedded object.


Top of Page Top of Page
© 2000 Microsoft and/or its suppliers. All rights reserved. Terms of Use.