## 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?
- Advantages of Using DirectDrawEx
- Creating DirectDraw Objects and Surfaces with DirectDrawEx
- Distinctions Between DirectDraw and DirectDrawEx

What Is DirectDrawEx?

DirectDrawEx is a dynamic-link library (DLL) that extends 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. When a surface is created using the DDSCAPS_DATAEXCHANGE flag, the surface will automatically be moved into video memory if there is enough video memory available, otherwise a system memory surface will be created. This stabilizes video memory surfaces and ensures that they will not be lost, even if system memory decides to move them into video memory in the future.

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 DirectDrawSurface objects 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.