Compartilhar via


CUnknown Class (Compact 2013)

3/26/2014

CBaseObject Class

     INonDelegatingUnknown Interface

          CUnknown

All 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.

If this is derived 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, 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.

Important

For readability, the following code example does not contain security checking or error handling. Do not use the following code in a production environment.

/* 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 you 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 this value 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 typically overrides 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

Member

Description

m_cRef

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

Member Functions

Member function

Description

CUnknown

Constructs a CUnknown object.

GetOwner

Returns an LPUNKNOWN pointer to the controlling unknown.

Implemented INonDelegatingUnknown Methods

Method

Description

NonDelegatingAddRef

Increments the reference count for an interface.

NonDelegatingQueryInterface

Returns an interface and increments the reference count.

NonDelegatingRelease

Decrements the reference count for an interface.

Requirements

Header

dshow.h,
Streams.h

Library

ole32.lib,
Ole32auth.lib,
Strmbase.lib,
Strmiids.lib,
uuid.lib

See Also

Reference

DirectShow Classes