Platform SDK: DirectX |
By calling the IDirectDraw7::EnumSurfaces method you can request that DirectDraw enumerate surfaces in various ways. The EnumSurfaces method enables you to look for surfaces that fit, or don't 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're enumerating all existing surfaces, you can set the lpDDSD parameter to NULL, otherwise set it to the address of an initialized DDSURFACEDESC2 structure that describes the surface for which you're 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 don't plan to use it (or when you're 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 IDirectDraw7::EnumSurfaces (no other flag combinations are valid). The DDSURFACEDESC2 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 DDSURFACEDESC2 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 DDSURFACEDESC2 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.
The following code fragment shows what this call could look like to enumerate all valid surface characteristics for 96×96 RGB or YUV surfaces.
DDSURFACEDESC2 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 isn't supported if it isn't enumerated. The attempt by DirectDraw 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.
By calling the DirectDraw7.GetSurfacesEnum method you can request that DirectDraw enumerate surfaces in various ways. The GetSurfacesEnum method enables you to look for surfaces that fit, or don't fit, a provided surface description. This method creates a DirectDrawEnumSurfaces object which is then used to query for individual surface descriptions.
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 flags parameter.
Enumerating existing surfaces This is the most common type of enumeration. You enumerate existing surfaces by calling GetSurfacesEnum, 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 flags parameter. If you're enumerating all existing surfaces, you can set the desc parameter to Nothing, otherwise set it to an initialized DDSURFACEDESC2 type that describes the surface for which you're looking.
The following code fragment shows what this call might look like to enumerate all of a DirectDraw object's existing surfaces. This assumes dd is a valid DirectDraw7 object and ddEnumSurfaces is a valid DirectDrawEnumSurfaces object.
Set ddEnumSurfaces = dd.GetSurfacesEnum(DDENUMSURFACES_DOESEXIST Or _ DDENUMSURFACES_ALL, ddsd2)
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 filled into the DirectDrawEnumSurfaces object.
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 DirectDraw7.GetSurfacesEnum (no other flag combinations are valid). The DDSURFACEDESC2 type 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 lFlags member of the DDSURFACEDESC2 type. Additionally, initialize the DDPIXELFORMAT type in the surface description and set its lFlags 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 DDSURFACEDESC2 structure, you can specify the desired dimensions in the lHeight and lWidth members. If you exclude these flags, DirectDraw uses the dimensions of the primary surface.
The following code fragment shows what this call could look like to enumerate all valid surface characteristics for 96×96 RGB or YUV surfaces.
Dim ddsd As DDSURFACEDESC2 ddsd.lFlags = DDSD_CAPS Or DDSD_PIXELFORMAT Or DDSD_HEIGHT Or DDSD_WIDTH ddsd.ddpfPixelFormat.lFlags = DDPF_YUV Or DDPF_RGB ddsd.lHeight = 96 ddsd.lWidth = 96 Set ddEnumSurfaces = dd.GetSurfacesEnum(DDENUMSURFACES_CANBECREATED Or _ DDENUMSURFACES_MATCH, ddsd)
When DirectDraw enumerates possible surfaces, it actually attempts to create a temporary surface that has the desired characteristics. If the attempt succeeds, then DirectDraw fills the DirectDrawEnumSurfaces object with only the characteristics that worked; it does return the temporary surface. Do not assume that a surface isn't supported if it isn't enumerated. The attempt by DirectDraw 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.