Chad Vernon
  • Home
  • Reel/Resume
  • Work
  • Resources
  • About
  • Contact
sideBar

Search

Categories

  • CG
  • cvxporter
  • Maya
    • API
    • Plug-ins
  • Personal

Archives

  • May 2012
  • March 2012
  • September 2011
  • June 2011
  • March 2011
  • December 2010
  • November 2010
  • September 2010
  • August 2010
  • July 2010
  • May 2010
  • April 2010
  • March 2010
  • December 2009
  • October 2009
  • September 2009
  • August 2009
  • July 2009
  • June 2009
  • May 2009
  • April 2009
  • March 2009
  • February 2009
  • January 2009
  • December 2008
  • November 2008
  • October 2008
  • September 2008
  • August 2008
  • July 2008
  • June 2008
  • May 2008
  • April 2008
  • March 2008
  • February 2008
  • January 2008
  • December 2007
  • November 2007
  • October 2007
  • September 2007
  • August 2007

Rss

  • Main Entries RSS
  • Comments RSS
Home » Resources » DirectX 9 » Creating Your First Window

Creating Your First Window

  CU_WindowCreation.zip (12.6 KiB, 4,289 hits)

Before we can create anything with DirectX, we first need to know how to create a window. To do this, we follow a few basic steps:

  1. Define and register a window class that describes the window we want to make.
  2. Create the window.
  3. Create the loop that will read messages and update the window based on input or game logic.
  4. Create an event handler, or window procedure, that responds to all events sent by the window (moving, resizing, etc…)

The following is basic Windows programming. So learn it once, then copy and paste it forever.

#include “stdafx.h”
#include “WinMain.h”

#define WINDOW_TITLE “Creating a Window”
#define WINDOW_WIDTH 300
#define WINDOW_HEIGHT 300

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR cmdLine, int cmdShow )
{

// Define the window
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );
wcex.hCursor = LoadCursor( hInstance, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = WINDOW_TITLE;
wcex.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );

// Register the window
RegisterClassEx( &wcex );

// Create the window
HWND hWnd = CreateWindow( WINDOW_TITLE, WINDOW_TITLE, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, hInstance, 0 );

// Adjust to actual desired size
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
AdjustWindowRect( &rect, GetWindowLong( hWnd, GWL_STYLE ), FALSE );
SetWindowPos( hWnd, 0, 0, 0, rect.right – rect.left, rect.bottom – rect.top, SWP_NOZORDER | SWP_NOMOVE );

ShowWindow( hWnd, SW_SHOW );
UpdateWindow( hWnd );

// Main loop
MSG msg;
while ( 1 )
{

// Only render when there are no messages
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{

if ( msg.message == WM_QUIT)
{

break;

}
TranslateMessage( &msg );
DispatchMessage ( &msg );

}
else
{

// Render a frame

}

}

return 0;

}

The WinMain function is the entry point of all Windows programs. If you’ve programmed a console application, this is the same as the Main function. First, we need to define the window class by filling out a WNDCLASSEX structure. This structure tells Windows all the properties of the window that we want to create. Check out MSDN for the details. Basically, this is where you can specify such things as a menu for the window as well as a custom icon. The lpfnWndProc member is set to a function pointer that we will write later on.

Registering the class is very simple. All we do is pass the address of our WNDCLASSEX structure we filled out as a parameter to the function, RegisterClassEx. Registering the window class tells Windows which WNDCLASSEX structure to use when we call CreateWindow.

With the window class defined and registered we can now create the window with CreateWindow. This is where we can specify the size and position of the window along with some basic window styles. The style flag I used, WS_OVERLAPPEDWINDOW, gives the window a border, title bar, close box, minimize box, and allows the window to be resized.

Usually when we specify a width and height, we intend those dimensions to form the rectangle that we will be drawing on, known as the client area. However, the window that is created thus far includes the pixels of the title bar and also the window menu if there was one. Therefore, we need to adjust the client area of the window to account for these additions. We can find what the client area needs to be by calling AdjustWindowRect. Using the adjusted RECT structure, we can update the dimensions of the window by calling SetWindowPos.

SetWindowPos

With the window all ready to go, we can display the window by calling ShowWindow and UpdateWindow.

The message loop is what continously updates the application until the user wants to quit. To be more efficient, we will only update and render a frame when there are no messages in the message queue. First we need to check if there are any messages that the window needs to take care of such as resizing, closing, etc. We check if there are any messages on the queue with PeekMessage. If there is a message, we test if the message is a quit message. If it’s not a quit message, we send the message off to our event handler by calling TranslateMessage and DispatchMessage. If there are no messages in the queue, we would update our game. Now we move on to the window procedure.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Application event handler.
Parameters:
[in] hWnd – Unique handle to the window.
[in] message – Incoming message.
[in] wParam – Parameter of the message (unsigned int).
[in] lParam – Parameter of the message (long).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{

switch ( message )
{

case WM_DESTROY:

PostQuitMessage( 0 );
return 0;

case WM_PAINT:

// Render a frame then validate the client area
ValidateRect( hWnd, 0 );
return 0;

}

return DefWindowProc( hWnd, message, wParam, lParam );

}

The window procedure, WndProc, is where we process all our messages. You can name this function whatever you want as long as you pass the same name to the WNDCLASSEX structure above. To process messages, just do a switch on the message to handle each case. There are a lot of possible messages, but usually you’ll just need a few. Here, I show how to process two messages: WM_DESTROY and WM_PAINT. The WM_DESTROY message is sent when the user closes a window. This usually means that the user wants to quit the program. Therefore, we need to tell the program to shutdown by calling PostQuitMessage. This puts a quit message onto the message queue so we can break from our loop in WinMain. The WM_PAINT message is sent whenever the window needs to repaint a portion of the client area, such as if another window is moved over our window. To handle this message, we would render our current frame and then call ValidateRect, which tells Windows that we’ve repainted the window. For all the messages that we didn’t handle, we send them off to let Windows deal with them with DefWindowProc.

That’s mostly all we need to know about Windows programming to start working with DirectX.

Laters, C

No Responses to “Creating Your First Window”

Subscribes to this topic Comment RSS or TrackBack URL

Leave A Reply

Allowed tag : <blockquote>, <p>, <code>, <em>, <small>, <ul>, <li>, <ol>, <a href=>..

 Username

 Email Address

 Website

Sticky: Always double check your comment before posting Please Note: Comment Moderation Maybe Active So There Is No Need To Resubmit Your Comments
Home » Resources » DirectX 9 » Creating Your First Window

© 2011 Chad Vernon