Microsoft DirectX 8.1 (C++)

Using COM Interfaces

When the object is created, the creation method returns an interface pointer. You can then use that pointer to access any of the interface's methods. The syntax is identical to that used with a pointer to a C++ method. The following code fragment extends the example given in the previous section. After creating the DirectPlay8 object, the example uses the IDirectPlay8Peer interface pointer returned by CoCreateInstance to initialize the object by calling the IDirectPlay8Peer::Initialize method. Error correction code is omitted for clarity.

IDirectPlay8Peer*  g_pDP = NULL;
...
CoInitialize( NULL );
...
hr = CoCreateInstance( CLSID_DirectPlay8Peer, NULL,CLSCTX_INPROC_SERVER,
                         IID_IDirectPlay8Peer, (LPVOID*) &g_pDP );
hr = g_pDP->Initialize( NULL, DirectPlayMessageHandler, 0 );

Requesting Additional Interfaces

In many cases, the interface pointer that you receive from the creation method may be the only one that you need. In fact, it is not uncommon for an object to export only one interface other than IUnknown. However, many objects export multiple interfaces, and you may need pointers to several of them. If you need more interfaces than the one returned by the creation method, there is no need to create a new object. Instead, you request another interface pointer by using the object's IUnknown::QueryInterface method.

If you create your object with CoCreateInstance, you can request an IUnknown interface pointer, and then call IUnknown::QueryInterface to request every interface you need. However, this approach is inconvenient if you need only a single interface, and it doesn't work at all if you use an object creation method that does not allow you to specify which interface pointer should be returned. In practice, you usually don't need to obtain an explicit IUnknown pointer because all COM interfaces inherit from or extend the IUnknown interface.

Extending an interface is similar to inheriting from a C++ class. The child interface exposes all of the parent interface's methods, plus one or more of its own. In fact, you will often see "inherits from" used instead of "extends". What you need to remember is that the inheritance is internal to the object. Your application cannot inherit from or extend an object's interface. However, you can use the child interface to call any of the child's or the parent's methods.

Because all interfaces are children of IUnknown you can use any of the interface pointers you already have for the object to call QueryInterface. When you do so, you must provide the IID of the interface you are requesting and the address of a pointer that will contain the interface pointer when the method returns. For example, the following code fragment calls IDirectSound8::CreateSoundBuffer to create a primary sound buffer object. This object exposes several interfaces. The CreateSoundBuffer method returns an IDirectSoundBuffer8 interface. The subsequent code then uses the IDirectSoundBuffer8 interface to call QueryInterface to request an IDirectSound3DListener8 interface.

IDirectSoundBuffer8* pDSBPrimary = NULL;
IDirectSound3DListener8* pDSListener;
...
if(FAILED(hr = g_pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL )))
  return hr;

if(FAILED(hr = pDSBPrimary->QueryInterface(IID_IDirectSound3DListener8,
                                           (LPVOID *)&pDSListener)))
  return hr;