Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
88 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

 Hungarian Notation
 Messages and

 Creating Windows
 Handling Messages
 Program Flow

 Printable version
 Discuss this article
 in the forums

The Series
 Beginning Windows

 Using Resources
 in Win32 Programs

 Tracking Your
 Window/Using GDI

 to DirectX

 Palettes and Pixels
 in DirectDraw

 Bitmapped Graphics
 in DirectDraw

 Developing the
 Game Structure

 Basic Tile Engines
 Adding Characters
 Tips and Tricks

Creating Windows

The good news is that all you need to create a window is a call to CreateWindowEx(). The bad news is that this function takes a lot of parameters. You're probably getting sick of these long lists by now, but this one isn't too bad. Here's the function prototype:

HWND CreateWindowEx( DWORD dwExStyle, // extended window style LPCTSTR lpClassName, // pointer to registered class name LPCTSTR lpWindowName, // pointer to window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // handle to menu, or child-window identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // pointer to window-creation data );

First things first: the return value. By now, all these crazy data types that Windows uses are probably starting to look familiar. If not, don't worry, you'll get used to it sooner than you think. The return type is HWND, which is a handle to a window. You'll want to store the value returned by CreateWindowEx(), as you'll need it as a parameter for several Windows functions. Now, let's tackle that parameter list. Many are self-explanatory.

DWORD dwExStyle: Extended window style is something you'll rarely use, so you can set this to NULL most of the time. If you're interested, the Help files for your compiler list a ton of constants beginning with WS_EX_ that can be used here.

LPCTSTR lpClassName: Remember when you named the class you created? Just pass that name here.

LPCTSTR lpWindowName: This is simply the text that will appear on the window's title bar.

DWORD dwStyle: The window style parameter allows you to specify what type of window you want to create. There are a lot of constants that can be used here, beginning with WS_, and they can be combined with the | operator. I'll list just a few of the common ones:

WS_POPUP A window that has no controls built into it.
WS_OVERLAPPED A window with simply a title bar and a border.
WS_OVERLAPPEDWINDOW A window with a title bar including all standard controls.
WS_VISIBLE Specifies that the window is initially visible.

The WS_OVERLAPPEDWINDOW constant is actually a combination of several other constants in order to create a standard window. Basically, you can follow these guidelines. If you want a window that can be maximized, minimized, resized, etc., use WS_OVERLAPPEDWINDOW. If you want a window with a title bar but which has a fixed size, use WS_OVERLAPPED. If you want a window that has no controls on it whatsoever, use WS_POPUP. Such a window will just appear as a black rectangle originally. This is what you'll probably use for writing fullscreen games. Also, always specify the WS_VISIBLE flag, unless for some reason you don't want anyone to see your window, or if you want to take care of some other things first, and display the window later.

int x, y: These are the coordinates on the screen at which the upper-left corner of the newly created window will appear.

int nWidth, nHeight: These are, you guessed it, the width and height of the window, in pixels.

HWND hWndParent: This is a handle to the parent window of the window you're creating. This is mostly used with controls such as checkboxes and pushbuttons. For creating a main window, set this to NULL, which represents the Windows desktop.

HMENU hMenu: This is a handle to the menu which should be attached to the window. If you're loading a resource menu -- after you learn how to do that -- you would use the LoadMenu() function. For a window with no menu attached, simply set this to NULL.

HINSTANCE hInstance: This is the instance of the application; again, pass the parameter that was passed to WinMain().

LPVOID lpParam: This is something you're not likely to use, especially for games, where only simple windows are needed. It's used for creating things like multiple document interfaces. Just set it to NULL.

At last, we have everything we need to create a window. Here's a sample call that would get the job done:

HWND hwnd; if (!(hwnd = CreateWindowEx(NULL, // extended style, not needed "Sample Class", // class identifier "Sample Window", // window title WS_POPUP | WS_VISIBLE, // parameters 0, 0, 320, 240, // initial position, size NULL, // handle to parent (the desktop) NULL, // handle to menu (none) hinstance, // application instance handle NULL))) // who needs it? return(0);

This might be something you'd use for a game, because it's a popup window. Notice that I've enclosed the CreateWindowEx() call inside an if statement. This is because if CreateWindowEx() fails, it returns NULL. The way this statement is set up, if the window can't be created for some reason, WinMain() simply returns and the program ends.

Now you've almost got enough to make a Windows program that creates a functional window. Almost. Remember when we created "Sample Class," and had to provide a pointer to a message handler function? We need to write that function before Windows will let us create anything.

Next : Handling Messages