百度首页 | 百度空间
 
查看文章
 
Direct Draw Initialization
2008/03/04 15:01

Direct Draw Initialization

Overview

Before you can use Direct Draw to manipulate the screen, you must first perform some initialization. This document describes the necessary and optional steps involved in Direct Draw initialization. See a reference for missing information about parameters, return values, etc.

Initialization Steps

1. (Optional) Enumerate the display devices on the target system by initiating a callback sequence with the DirectDrawEnumerateEx() API function. This is necessary only if you wish to take advantage of multiple monitors on a Windows 98 system. DirectDrawEnumerateEx() has the following prototype:

HRESULT WINAPI DirectDrawEnumerateEx( LPDDENUMCALLBACKEXlpCallback, LPVOID lpContext, DWORD dwFlags);

lpCallback is the address of the callback function that you write. More on this later. lpContext is a pointer to a structure that will allow you to communicate with the callback function, such as a linked list of strings & GUIDs. Pass in zero for dwFlags.

Now back to the callback function. The user-defined callback function must have the following prototype:

BOOL WINAPI MyFunctionName( GUID FAR*lpGUID, LPSTRlpDriverDescription, LPSTRlpDriverName, LPVOIDlpContext, HMONITOR hm );

lpGUID is a globally unique identifier of the display device that is being described in the current activation of the callback function. You must store the GUID in order to request the use of a particular display device (use the user-defined structure pointed to by lpContext to accomplish this). lpDriverDescription will contain a text description of the device that is being described. lpDriverName can safely be ignored. hm is the handle to the monitor that the display device that is being described is connected to. If hm is anything but NULL, then you have found a device with a second monitor attached.

Enumeration continues as long as the callback function returns true. So when you have found the device(s) you were looking for, return false to stop the callback sequence.


2. Create an instance of a Direct Draw object. This is accomplished by declaring a pointer to a Direct Draw object and then using the Windows API function DirectDrawCreate() to create the object. DirectDrawCreate() has the following prototype:

HRESULT WINAPI DirectDrawCreate( GUID FAR*lpGUID, LPDIRECTDRAWFAR *lplpDD, IUnknown FAR*pUnkOuter );

lpGUID is a pointer to the globally unique identifier of the display device you are requesting access to. You may either specify a value that was obtained in display device enumeration (see step 1 above), or you may pass in NULL to specify the "default" device, which is the primary screen. lplpDD is a pointer to a Direct Draw object, which will be created by DirectDrawCreate(). Pass in NULL for pUnkOuter.

For example,

LPDIRECTDRAW DDrawObj;
if (FAILED(DirectDrawCreate(NULL ,&DDrawObj,NULL)))
    throw (EX_DDRAW_CREATE);        // throw an exception

DirectDrawCreate() returns DD_OK if the Direct Draw object was successfully created.


3. The Direct Draw object created above is a COM object that inherits from IUnknown. Optionally, you may now get a later interface by calling IUnknown::QueryInterface(). This is necessary to take advantage of the latest features of Direct Draw, like the RestoreAllSurfaces() method. IUnknown::QueryInterface() has the following prototype:

HRESULT QueryInterface( REFIID riid, LPVOID *obp );

For example, you could get a Direct Draw 4 (the latest) interface as shown below:

LPDIRECTDRAW4 displayDevice;
if ((DDrawObj->QueryInterface(IID_IDirectDraw4, (LPVOID*) &displayDevice)) != S_OK)
    throw (EX_DDRAW_NEW_INT);

displayDevice now points to a Direct Draw 4 interface (or an exception was thrown). QueryInterface returns S_OK if the new interface was successfully created. Note that Direct Draw is backward compatible, so your legacy code should still work correctly with each new release of DirectX. Once you have created a newer interface, you may safely discard the old Direct Draw object by calling IUnknown::Release(), which takes no parameters.


4. Set the cooperative level by calling IDirectDraw4::SetCooperativeLevel(), which has the following protoype:

HRESULT SetCooperativeLevel( HWND hWnd, DWORDdwFlags );

hWnd is used by the application. dwFlags specifies a number of options. See a reference for details.

For example, to specify full-screen, exclusive mode access to the screen,

if ( FAILED( displayDevice->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN )))
    throw (EX_DDRAW_COOP);

Requesting full-screen, exclusive mode will often fail if other applications that use the GDI to modify the screen are running.


5. (Optional) If desired, change the display mode to the desired mode by calling IDirectDraw4::SetDisplayMode(). SetDisplayMode() has the following prototype:

HRESULT SetDisplayMode( DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags );

For example, to specify 800 X 600, 16-bit color mode:

if (FAILED(displayDevice->SetDisplayMode(800,600,16,0,0)))
    throw (EX_DDRAW_MODE);

SetDisplayMode returns DD_OK if no error occurs.



Example

The following function demonstrates how to initialize DirectDraw:

IDirectDraw4 * InitDirectDraw(HWND hWnd)
    {
    IDirectDraw * throwAway;
    IDirectDraw4 * displayDevice;

    // Get a DirectDraw 1 interface
    if (FAILED(DirectDrawCreate(NULL ,&throwAway, NULL)))
        throw (EXC_DDRAW_INIT);        // throw an exception

    // query for a direct draw 4 interface
    if ((throwAway->QueryInterface(IID_IDirectDraw4, (LPVOID*) &displayDevice)) != S_OK)
        throw (EXC_DDRAW_INIT);

    // try for full-screen, exclusive mode
    if ( FAILED( displayDevice->SetCooperativeLevel( hWnd, DDSCL_EXCLUSIVE |
        DDSCL_FULLSCREEN )))
        throw (EXC_DDRAW_INIT);

    // change disp mode to 800x600x16bpp
    if (FAILED(displayDevice->SetDisplayMode(800, 600, 16, 0, 0)))
        throw (EXC_DDRAW_INIT);

    // release the DirectDraw1 interface
    throwAway->Release();

    // give the monitor time to synch
    Sleep(1000);

    return displayDevice;
    }

If successful, this function returns a pointer to a DirectDraw4 interface. Otherwise, it throws an integer exception, EXC_DDRAW_INIT.

Definitions

Cooperative Level - describes how a Direct Draw application will cooperate with the rest of the programs that are executing on the system. For example, a full-screen, exclusive cooperative level will not allow other programs to generate output to the screen. Note that page flipping is not available unless you use full-screen, exclusive mode.

COM - acronym for Component Object Model. Roughly, COM is a standard that specifies how COM objects can interact with other objects.

Author: Rodney Myers -- 5/15/99

http://www.mtsu.edu/~csjudy/directX/DirectDraw/Initialization.html


类别:Windows Application | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu