Enumerating Surfaces
A version of this page is also available for
4/8/2010
By calling the IDirectDraw::EnumSurfaces method you can request that DirectDraw enumerate surfaces in various ways. The EnumSurfaces method enables you to look for surfaces that fit, or do not fit, a provided surface description. DirectDraw calls a EnumSurfacesCallback that you include with the call for each enumerated surface.
There are two general ways to search — you can search for surfaces that the DirectDraw object has already created, or for surfaces that the DirectDraw object is capable of creating at the time (given the surface description and available memory). You specify what type of search you want by combining flags in the method's dwFlags parameter.
Enumerating existing surfaces
This is the most common type of enumeration.
You enumerate existing surfaces by calling EnumSurfaces, specifying a combination of the DDENUMSURFACES_DOESEXIST search-type flag and one of the matching flags (DDENUMSURFACES_MATCH, DDENUMSURFACES_NOMATCH, or DDENUMSURFACES_ALL) in the dwFlags parameter.
If you are enumerating all existing surfaces, you can set the lpDDSD parameter to NULL, otherwise set it to the address of an initialized DDSURFACEDESC structure that describes the surface for which you are looking.
You can set the third parameter, lpContext, to an address that will be passed to the enumeration function you specify in the fourth parameter, lpEnumSurfacesCallback.
The following code fragment shows what this call might look like to enumerate all of a DirectDraw object's existing surfaces.
HRESULT ddrval;
ddrval = lpDD->EnumSurfaces(DDENUMSURFACES_DOESEXIST |
DDENUMSURFACES_ALL, NULL, NULL,
EnumCallback);
if (FAILED(ddrval))
return FALSE;
When searching for existing surfaces that fit a specific description, DirectDraw determines a match by comparing each member of the provided surface description to those of the existing surfaces.
Only exact matches are enumerated. DirectDraw increments the reference counts of the enumerated surfaces, so make sure to release a surface if you do not plan to use it (or when you are done with it).
Enumerating possible surfaces
This type of enumeration is less common than enumerating existing surfaces, but it can be helpful to determine if a surface is supported before you attempt to create it.
To perform this search, combine the DDENUMSURFACES_CANBECREATED and DDENUMSURFACES_MATCH flags when you call IDirectDraw::EnumSurfaces (no other flag combinations are valid).
The DDSURFACEDESC structure you use with the call must be initialized to contain information about the surface characteristics that DirectDraw will use.
To enumerate surfaces that use a particular pixel format, include the DDSD_PIXELFORMAT flag in the dwFlags member of the DDSURFACEDESC structure.
Additionally, initialize the DDPIXELFORMAT structure in the surface description and set its dwFlags member to contain the desired pixel format flags — DDPF_RGB, DDPF_YUV, or both. You need not set any other pixel format values.
If you include the DDSD_HEIGHT and DDSD_WIDTH flags in the DDSURFACEDESC structure, you can specify the desired dimensions in the dwHeight and dwWidth members. If you exclude these flags, DirectDraw uses the dimensions of the primary surface.
Code Example
The following code example shows what this call could look like to enumerate all valid surface characteristics for 96×96 RGB or YUV surfaces.
Note
To make the following code example easier to read, security checking and error handling are not included. This code example should not be used in a release configuration unless it has been modified to include them.
DDSURFACEDESC ddsd;
HRESULT ddrval;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT |
DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddpfPixelFormat.dwFlags = DDPF_YUV | DDPF_RGB;
ddsd.dwHeight = 96;
ddsd.dwWidth = 96;
ddrval = lpDD->EnumSurfaces(
DDENUMSURFACES_CANBECREATED | DDENUMSURFACES_MATCH,
&ddsd, NULL, EnumCallback);
if (ddrval != DD_OK)
return FALSE;
When DirectDraw enumerates possible surfaces, it actually attempts to create a temporary surface that has the desired characteristics.
If the attempt succeeds, then DirectDraw calls the provided EnumSurfacesCallback function with only the characteristics that worked; it does not provide the callback function with pointer to the temporary surface.
Do not assume that a surface is not supported if it is not enumerated. DirectDraw's attempt to create a temporary surface could fail due to memory constraints that exist at the time of the call, resulting in those characteristics not being enumerated, even if the driver actually supports them.