Using Application Windows with DXUT

Your application can handle most window management tasks by using just a few functions in DXUT.

Creating a Window

Creating a window for a Direct3D application involves the following steps:

  1. Defining a WindowProc to respond to the proper window messages.
  2. Setting up the WNDCLASS.
  3. Using RegisterClass.
  4. Using CreateWindow.

These steps can cause bugs if not done correctly. Although they may not be very exciting for a Direct3D programmer, they are required in every application. The framework simplifies this process with the DXUTCreateWindow function:

HRESULT DXUTCreateWindow(
    const WCHAR *strWindowTitle = L"Direct3D Window",
    HINSTANCE hInstance         = NULL,
    HICON hIcon                 = NULL,
    HMENU hMenu                 = NULL,
    INT x                       = CW_USEDEFAULT,
    INT y                       = CW_USEDEFAULT
);

All parameters are optional:

In the simplest case, an application can call the DXUTCreateWindow function as follows:

DXUTCreateWindow( L"My New Game" );

Calling the function with only the first parameter, strWindowTitle, will cause the framework to create the window and handle the important window messages automatically. The handle to the window can be retrieved if needed by calling DXUTGetHWND.

If the application is to respond to window messages, then it can use DXUTSetCallbackMsgProc to set a callback function:

void DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallbackMsgProc, 
  void* pUserContext = NULL );

The pCallbackMsgProc parameter is an LPDXUTCALLBACKMSGPROC callback function with the following syntax:

LRESULT CALLBACK FUNCTION MsgProc(
    HWND   hWnd,
    UINT   uMsg,
    WPARAM wParam,
    LPARAM lParam,
    BOOL*  pbNoFurtherProcessing,
    void*  pUserContext 
    )
{
    return 0;
}

In this callback function, the application does not need to respond to any messages because all of the important messages will still be handled by the framework. To prevent the framework from handling messages, the application can set *pbNoFurtherProcessing to TRUE. (See LPDXUTCALLBACKMSGPROC.) However, be cautious when using this setting, because it may prevent the framework from behaving correctly.

Using Your Own Window

If you want the application to create its own window and use it with the framework instead of letting DXUT handle window operations, then you can create a window and use the DXUTSetWindow function:

HRESULT DXUTSetWindow(
    HWND hWndFocus,
    HWND hWndDeviceFullScreen,
    HWND hWndDeviceWindowed,
    BOOL bHandleMessages = TRUE
);

This function takes three handles to windows, but all typically will be the same unless the windowed application is in a different window than the full-screen application. The focus window handle is provided to inform Direct3D when the application is switched to background upon an ALT+TAB, mouse click, or other user input. The application usually should pass the focus window handle to the DXUTSetWindow function, regardless of how many Direct3D devices it creates.

In addition to initializing the framework with a window, the application needs to notify the framework about the window messages that the window receives in order for the framework to behave correctly. If the framework creates the window, window messages are handled automatically. Otherwise, the application can pass window messages to the framework from inside the window's WindowProc callback function by using the DXUTStaticWndProc function, which is defined as follows:

	LRESULT CALLBACK DXUTStaticWndProc(
    HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
);

Although it is not recommended, you can alternately duplicate the functionality found in the function if you do not want the application to use DXUTStaticWndProc.