Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

Client memory surfaces are simply DirectDrawSurface objects that use system memory that your application has previously allocated to hold image data. Creating such a surface is not common, but it is not difficult to do and it can be useful for applications that need to use DirectDraw surface capabilities on existing memory buffers.

Like creating all surfaces, DirectDraw needs information about the dimensions of the surface (measured in pixels) and the surface pitch (measured in bytes), as well as the surface's pixel format.

However, unlike creating other types of surfaces, this information does not tell DirectDraw how you want the surface to be created, it tells DirectDraw how you have already created it.

You set these characteristics, plus the memory address of the buffer you have allocated, in the DDSURFACEDESCstructure you pass to the IDirectDraw::CreateSurfacemethod.

A client memory surfaces works just like a normal system-memory surface, with the exception that DirectDraw does not attempt to free the surface memory when it is no longer needed; freeing client allocated memory is the application's responsibility.

Code Example

The following code example demonstrates how to allocate memory and create a IDirectDrawSurfaceobject for a 64×64 pixel 24-bit RGB surface.

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.
Copy Code
// For this example, g_lpDD is a valid IDirectDraw interface
pointer.
 
#define WIDTH  64 // in pixels
#define HEIGHT 64
#define DEPTH  3  // in bytes (3bytes == 24 bits)
 
	HRESULT hr;
	LPVOID  lpSurface  = NULL;
	HLOCAL  hMemHandle = NULL;
	DDSURFACEDESC ddsd;
	LPDIRECTDRAWSURFACE lpDDS;
 
	// Allocate memory for a 64 by 64, 24-bit per pixel buffer.
	// REMEMBER: The application is responsible for freeing this
	//		 buffer when it is no longer needed.
	if (lpSurface = malloc((size_t)WIDTH*HEIGHT*DEPTH))
		ZeroMemory(lpSurface, (DWORD)WIDTH*HEIGHT*DEPTH);
	else
		return DDERR_OUTOFMEMORY;
 
	// Initialize the surface description.
	ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));
	ZeroMemory(&ddsd.ddpfPixelFormat, sizeof(DDPIXELFORMAT));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_LPSURFACE |
					DDSD_PITCH | DDSD_PIXELFORMAT;
	ddsd.dwWidth = WIDTH;
	ddsd.dwHeight= HEIGHT;
	ddsd.lPitch  = (LONG)DEPTH * WIDTH;
	ddsd.lpSurface = lpSurface;
 
	// Set up the pixel format for 24-bit RGB (8-8-8).
	ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
	ddsd.ddpfPixelFormat.dwFlags= DDPF_RGB;
	ddsd.ddpfPixelFormat.dwRGBBitCount = (DWORD)DEPTH*8;
	ddsd.ddpfPixelFormat.dwRBitMask	= 0x00FF0000;
	ddsd.ddpfPixelFormat.dwGBitMask	= 0x0000FF00;
	ddsd.ddpfPixelFormat.dwBBitMask	= 0x000000FF;
 
	// Create the surface
	hr = g_lpDD->CreateSurface(&ddsd, &lpDDS, NULL);
	return hr;