The component object model dictates that objects update their functionality not by changing the methods within existing interfaces, but by extending new interfaces that encompass new features. In keeping existing interfaces static, an object built on COM can freely extend its services while maintaining compatibility with older applications.
DirectX components follow this philosophy. For example, the DirectDraw component supports three interfaces to access a DirectDrawSurface object: IDirectDrawSurface, IDirectDrawSurface2, IDirectDrawSurface3 and IDirectDrawSurface4. Each version of the interface supports the methods provided by its ancestor, adding new methods to support new features. If your application doesn't need to use these new features, it doesn't need to retrieve newer interfaces. However, to take advantage of features provided by a new interface, you must call the object's IUnknown::QueryInterface method, specifying the globally unique identifier (GUID) of the interface you want to retrieve. Interface GUIDs are declared in the corresponding header file.
The following example shows how to query for a new interface:
LPDIRECTDRAW lpDD1;
LPDIRECTDRAW2 lpDD2;
ddrval = DirectDrawCreate( NULL, &lpDD1, NULL );
if( FAILED(ddrval))
goto ERROROUT;
// Query for the IDirectDraw2 interface
ddrval = lpDD1->QueryInterface(IID_IDirectDraw2, (void **)&lpDD2);
if( FAILED(ddrval))
goto ERROROUT;
// Now that we have an IDirectDraw2, release the original interface.
lpDD1->Release();
In some rare cases, a new interface will not support some methods provided in a previous interface version. The IDirect3DDevice2 interface is an example of this type of interface. If your application requires features provided by an earlier version of an interface, you can query for the earlier version in the same way as shown in the preceding example, using the GUID of the older interface to retrieve it.