Using DirectDrawEx


This article provides a brief overview of DirectDrawEx and how it extends the functionality of a DirectDraw object as described in the Microsoft DirectX® SDK.

Contents of this article:

What Is DirectDrawEx?

DirectDrawEx is a dynamic-link library (DLL) that embellishes current functionality of DirectDraw, enhancing existing features and providing new functionality. DirectDrawEx also exposes new interfaces that applications can use when you include the ddrawex.h header file.

To create a DirectDraw object that can use the extended features provided by DirectDrawEx, you must create the object by using the IDirectDrawFactory interface. A DirectDraw object created with the IDirectDrawFactory interface will support the IDirectDraw3 interface, aggregation of DirectDraw surfaces, data exchange, and palette mapping, in addition to the features of DirectDraw objects described in the DirectX SDK.

Advantages of Using DirectDrawEx

The primary advantage of creating a DirectDraw object through the IDirectDrawFactory interface is that it exposes the IDirectDraw3 interface. The IDirectDraw3 interface inherits all the functionality of the IDirectDraw and the IDirectDraw2 interfaces and provides a new method that can retrieve a pointer to an IDirectDrawSurface interface, given a handle to a device context.

To obtain the IDirectDraw3 interface, you must call the IDirectDrawFactory::CreateDirectDraw method to create the DirectDraw object and expose the IUnknown and IDirectDraw interfaces. Applications can then call QueryInterface to obtain a pointer to the IDirectDraw3 interface. To view sample code that demonstrates this, see Creating DirectDraw Objects and Surfaces with DirectDrawEx.

Another advantage of using DirectDrawEx over using DirectDraw is that you can now aggregate inner objects with outer objects by using the IDirectDraw3::CreateSurface method. Formerly, IDirectDraw::CreateSurface and IDirectDraw2::CreateSurface did not provide COM aggregation features. For a thorough description of how IDirectDraw3 implements aggregation see, IDirectDraw3::CreateSurface.

Finally, DirectDrawEx now also provides the DDSCAPS_DATAEXCHANGE flag for the DDSCAPS structure's dwcaps member. Setting this flag in conjunction with the DDSCAPS_OWNDC flag enables applications to call the IDirectDrawSurface::GetDC method to lock the device context for as long they require, without holding a lock on the surface.

Creating DirectDraw Objects and Surfaces with DirectDrawEx

The following sample code demonstrates how to create a DirectDraw object by using DirectDrawEx, and get a pointer to the IDirectDraw3 interface. The code shows how to create and call DirectDraw objects.


#include ddrawex.h

void CreateDDEx()
{
	//Declarations
	HRESULT 	hr;
	IDirectDraw 	*pDD;    
	IDirectDraw3 	*pDD3; 
	IDirectDrawFactory *pDDF;

	//Initialize COM library	
	CoInitialize(NULL);


	//Create a DirectDrawFactory object and get  
	//an IDirectDrawFactory interface pointer
	CoCreateInstance(CLSID_DirectDrawFactory, NULL, CLSCTX_INPROC_SERVER, 
							IID_IDirectDrawFactory, (void **)&pDDF);

	//Call the IDirectDrawFactory::CreateDirectDraw method to create the 
	//DirectDraw surface, set the cooperative level, and get the address 
	//of an IDirectDraw interface pointer
	hr = (pDDF->CreateDirectDraw(NULL, GetDesktopWindow(), DDSCL_NORMAL, 
				NULL, NULL, &pDD));

	if (hr !=DD_OK) {//error checking
	}
	
	//Now query for the new IDirectDraw3 interface, and release the old one.
	hr =(pDD->QueryInterface(IID_IDirectDraw3, (LPVOID*)&pDD3));
	
	if (hr !=S_OK) {//error checking
	}
	
	//Release IDirectDraw
	pDD->Release();
	pDD= NULL;	

	//Initialize the DDSURFACEDESC structure for the primary surface
	ZeroMemory(&ddsd, sizeof(ddsd));
      ddsd.dwSize = sizeof(ddsd);    
	ddsd.dwFlags = DDSD_CAPS;
      ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; 
      hr = pDD3->CreateSurface(&ddsd, &pPrimarySurface, NULL);
	

	//Do whatever you need to do in your application here with your 
	//DirectDraw surface

	//Release IDirectDraw3, IDirectDrawFactory, and the DirectDraw surface
	pDD3->Release();
	pDDF->Release();
	pPrimarySurface->Release();    

	//Close the COM library
	CoUninitialize();
}

Distinctions Between DirectDraw and DirectDrawEx

One important distinction to note between DirectDrawEx and DirectDraw is that applications that have created multiple DirectDrawSurfaces through a DirectDrawEx surface must release every DirectDraw surface.

Also, calling the GetDDInterface method from any surface created under DirectDrawEx will return a pointer to the IUnknown interface instead of a pointer to an IDirectDraw interface. Applications must use the IUnknown::QueryInterface method to retrieve the IDirectDraw, IDirectDraw2, or IDirectDraw3 interfaces.

Finally, DirectDrawEx does not currently support blitting between surfaces created by DirectDrawEx and surfaces created by DirectDraw. Applications should blit only between similar surfaces.

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.