The EnumDrivers function is called by the InitApp function just before InitApp creates the application's scene and camera.
The COM interface is really an interface to a DirectDraw object, so the first thing this enumeration function does is call the DirectDrawCreate function to create a DirectDrawObject. Then EnumDrivers uses the QueryInterface method to create an IDirect3D interface. Notice that the C implementation of QueryInterface requires that you pass the address of the interface identifier as the second parameter, not simply the constant itself (as in the C++ implementation).
The enumeration is handled by the IDirect3D::EnumDevices method, which depends on the locally defined enumDeviceFunc callback function. For more information about this callback function, see The enumDeviceFunc Callback Function.
Notice that IDirect3D::EnumDevices is a Direct3D method, not a Direct3DRM method; there is no enumeration method in the Retained-Mode API. This is a good example of the natural use of both Retained-Mode and Immediate-Mode methods in a single application.
/////////////////////////////////////////////////////////////////////
//
// EnumDrivers
// Enumerate the available D3D drivers and choose one.
//
/////////////////////////////////////////////////////////////////////
static BOOL
EnumDrivers(HWND win)
{
LPDIRECTDRAW lpDD;
LPDIRECT3D lpD3D;
HRESULT rval;
// Create a DirectDraw object and query for the Direct3D interface
// to use to enumerate the drivers.
DirectDrawCreate(NULL, &lpDD, NULL);
rval = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirect3D,
(void**) &lpD3D);
if (rval != DD_OK) {
lpDD->lpVtbl->Release(lpDD);
return FALSE;
}
// Enumerate the drivers, setting CurrDriver to -1 to initialize the
// driver selection code in enumDeviceFunc.
myglobs.CurrDriver = -1;
lpD3D->lpVtbl->EnumDevices(lpD3D, enumDeviceFunc,
&myglobs.CurrDriver);
// Ensure at least one valid driver was found.
if (myglobs.NumDrivers == 0) {
return FALSE;
}
lpD3D->lpVtbl->Release(lpD3D);
lpDD->lpVtbl->Release(lpDD);
return TRUE;
}