Menu
Win32 Tutorials

Win32

Creating Windows



Tutorials > Win32 > Creating Windows

View Full Source

Introduction

The basis of windows programming deals with windows not surprisingly. This tutorial will explain how to create windows to house your windows controls or graphical displays. There is quite a lot of code involved with creating a window but we'll try to go through it slowly and carefully.

Contents of main.cpp :


#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
		LPSTR lpCmdLine, int nShowCmd)
{

Every window must belong to a window class. The name of the class is specified as a normal string. Below, we give the name of the class we are going to use "ClassName".

	LPCTSTR className = "ClassName";

Next we have to create the windows class. This is done by filling a WNDCLASSEX structure. All properties need to be set. Each property will be explained separately below.

	WNDCLASSEX wc;

UINT cbSize - This specifies the size of the structure and should always be set to sizeof(WNDCLASSEX).

	wc.cbSize = sizeof(WNDCLASSEX);

UINT style - This is used to specify various properties of the windows class. These are known as Class Styles and each flag begins with a CS_. The most common styles are given below :

Flag Description
CS_CLASSDC We will explain a device context(DC) later but this specifies that one device context is shared between all windows created with this class.
CS_DBLCLKS This is needed if you want to be able to detect double mouse clicks made on the window.
CS_HREDRAW The window is redrawn if there is a change in the window's width or if the window is moved horizontally.
CS_NOCLOSE Disables the close option on the window menu.
CS_OWNDC A unique device context is created for each window created. This is the opposite to CS_CLASSDC.
CS_PARENTDC This sets the clipping rectangle of the child window to that of the parent window. This allows the child window to be able to draw on the parent window.
CS_VREDRAW The window is redrawn if there is a change in the window's height or if the window is moved vertically.

Below, we only want to make sure the window is redrawn if moved or resized.

	wc.style = CS_HREDRAW | CS_VREDRAW;

WNDPROC lpfnWndProc - This is a function pointer to the windows messaging function. It should point to the function that will be used to process windows messages sent to the window. We assign this to DefWindowProc. The DefWindowProc function is used to process any messages not explicitly processed by the application. In this tutorial we are not processing any messages, so we pass everything onto the DefWindowProc function.

	wc.lpfnWndProc = DefWindowProc;

int cbClsExtra - This specifies the number of extra bytes to allocate after the WNDCLASSEX structure. We only need to allocate extra memory if we are storing the WNDCLASSEX information in some other structure. We can therefore set this to 0.

	wc.cbClsExtra = 0;

int cbWndExtra - This specifies the number of extra bytes to allocate following the window instance. This we can also set to 0.

	wc.cbWndExtra = 0;

HINSTANCE hInstance - This must be given the handle to the instance of your current application.

We have this handle but if you didn't, you could use the GetModuleHandle function. This function takes 1 parameter which is used to specify the module name. If you pass it NULL it will return the current application's instance.

	wc.hInstance = hInstance;

HICON hIcon - An HICON is a handle to an icon. This property is used to specify the icon that will appear in the top left of the window ie. in the title bar on the left.

An icon can be loaded by using the LoadIcon function. This function takes 2 parameters. The first parameter takes the instance of the application ie. hInstance. The second parameter takes the name of the resource to be loaded. This would be the case if an icon was loaded in what is called a resource script. If you do not have your own icon you can load a predefined icon. This is done by passing NULL as the first parameter and specifying the ID for the icon. The most common of these ID's is given below :

ID Description
IDI_APPLICATION Default application icon
IDI_HAND Hand-shaped icon
IDI_EXCLAMATION Exclamation icon
IDI_INFORMATION Asterix icon
IDI_QUESTION Question mark icon
IDI_WINLOGO Default application icon if using XP, otherwise windows logo.

The code below will simply load the windows logo as the main icon.

	wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);

HCURSOR hCursor - An HCURSOR is a handle to a cursor. This specifies the cursor that will be displayed when your mouse is within the window. The LoadCursor function can be used to load the appropriate cursror. The parameters for LoadCursor work in the exact same way as LoadIcon. The most commonly used predefined cursors are given below :

ID Description
IDC_APPSTARTING Arrow and small hourglass
IDC_ARROW Standard Arrow
IDC_CROSS Crosshair
IDC_HAND Hand
IDC_HELP Arrow and small question mark
IDC_IBEAM I-beam
IDC_NO Slashed Circle
IDC_WAIT Hourglass

We load the standard arrow below.

	wc.hCursor = LoadCursor(NULL, IDC_ARROW);

HBRUSH hbrBackground - An HBRUSH is a handle to a brush. This is used to specify the background color of your window. A number of colors are available by using COLOR_*. These are the standard windows colors ie. COLOR_WINDOW, COLOR_SCROLLBAR, COLOR_MENU, COLOR_WINDOWTEXT, etc.

An alternative to this method is to use the GetStockObject function. This retrieves the handle to a brush specified by you. This function takes a parameter which specifies the color of the brush eg. BLACK_BRUSH, GRAY_BRUSH, WHITE_BRUSH, DKGRAY_BRUSH, etc.

Below, the COLOR_WINDOW + 1 specifies a white background.

	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

LPCTSTR lpszMenuName - This specifies the name of the menu attached to the window. We do not have a menu and we therefore give it the value of NULL.

	wc.lpszMenuName = NULL;

LPCTSTR lpszClassName - This specifies the name given to the class. We simply use the string we created at the beginning of the program.

	wc.lpszClassName = className;

HICON hIconSm - This is used to specify the small icon for the program ie. the icon that is displayed in your taskbar. This works in the exact same way as the hIcon above.

	wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

Next we need to register the class. This is necessary to be able to create windows using this class. To register a class, the RegisterClassEx function is used. This function takes one parameter, being the WNDCLASSEX structure that was previously filled. The return value is 0 if there was any error. An UnregisterClass method is also available to unregister a class. This is not needed though as all classes are unregistered when the application terminates.

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, "Error registering class",
			"Error", MB_OK | MB_ICONERROR);
		return 1;
	}

The next function that will take a lot of explaining is the CreateWindowEx function. This creates a window using a previously registered class. If successful, a handle to a window (HWND) is returned. If any error occurred, 0 is returned. Each parameter will be explained separately.

	HWND hwnd = CreateWindowEx(

DWORD dwExStyle - A DWORD is a 32-bit unsigned integer. This parameter specifies an extended style given to the window. These flags start with a WS_EX_* and can be separated using | (or) operators. Some common flags are given below :

Flag Description
WS_EX_ACCEPTFILES The window accepts drag-drop files.
WS_EX_APPWINDOW This will send a top-level window to the taskbar when this window becomes visible.
WS_EX_CLIENTEDGE The window has a border with a sunken edge.
WS_EX_CONTEXTHELP A ? appears in the title bar that the user can click on for help.
WS_EX_MDICHILD This creates a multiple document interface (MDI) child window. MDI interfaces will be spoken about in a future tutorial.
WS_EX_TRANSPARENT The window appears transparent.
WS_EX_WINDOWEDGE The window has a border with a raised edge.

We do not want any of these extended styles, so we leave the parameter as 0.

		0,

LPCTSTR lpClassName - This is the name of the class that this window will belong to. We therefore pass it the class' name that was previously registered.

		className,

LPCTSTR lpWindowName - This specifies the text that will appear in the title bar of the window.

		"05 - Creating Windows",

DWORD dwStyle - This parameter specifies what style the window should use. This is different to the extended styles. There is an old function CreateWindow. The CreateWindowEX function was created to allow the extended styles to be added. The most commonly used flags are given below :

Flag Description
WS_BORDER The window has a thin-line border.
WS_CAPTION Creates a window with a title bar.
WS_CLIPCHILDREN This is used when creating the parent window. All areas covered by the child windows are not drawn.
WS_CLIPSIBLINGS This causes any sibling windows that the new window overlaps to not be drawn.
WS_HSCROLL The window has a horizontal scroll bar.
WS_MINIMIZE The window starts minimized.
WS_MAXIMIZE The window starts maximized.
WS_MAXIMIZEBOX The window has a maximize button in the title bar.
WS_MINIMIZEBOX The window has a minimize button.
WS_OVERLAPPEDWINDOW Creates a window with a title bar and border. Includes styles WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX and WS_MAXIMIZEBOX.
WS_POPUP Creates a popup window.
WS_SYSMENU The window has a menu in its title bar.
WS_THICKFRAME Creates a window with a sizing border.
WS_VISIBLE The window is created initially visible. This takes away the need for the ShowWindow function.
WS_VSCROLL The window is created with a vertical scroll bar.

We only need the WS_OVERLAPPEDWINDOW in this tutorial.

		WS_OVERLAPPEDWINDOW,

int x & int y - These parameters specify the starting x and y positions of the window where (0,0) is the top left corner of the screen. You can use the system's defaults by using CW_USEDEFAULT.

		CW_USEDEFAULT, CW_USEDEFAULT,

int nWidth & int nHeight - These parameters specify the width and height of the window in pixels.

		300, 300,

HWND hwndParent - This specifies the handle to the parent of the window. As we have no parent, NULL is passed.

		NULL,

HMENU hMenu - An HMENU is a handle to a menu. This indicates the menu that is attached to the window. Because we do not have a menu, NULL is passed.

		NULL,

HINSTANCE hInstance - This parameter is used to specify the instance of the current program.

		hInstance,

LPVOID lpParam - This is not used unless we are creating an MDI client window. We therefore pass it the value of NULL.

		NULL
		);

	if (!hwnd)
	{
		MessageBox(NULL, "Error creating window",
			"Error", MB_OK | MB_ICONERROR);
		return 1;
	}

Because we didn't give the window a WS_VISIBLE style, we need to explicitly show the window. This can be done using the ShowWindow function. The function takes 2 parameters. The first is the handle to the window that you want to show and the second is how you want the window shown. As this is passed onto the program at startup, you can use the nShowCmd variable. If you want to specify your own action, you can use one of the commonly used flags below :

Flag Description
SW_HIDE Hides the window and activates another window.
SW_MAXIMIZE Maximizes the window.
SW_MINIMIZE Minimizes the window.
SW_SHOW Activates the window and displays it using its size and position.

	ShowWindow(hwnd, nShowCmd);
	
	return 0;
}

Well done. This has been a very long tutorial. Hopefully you have found that it has been covered in great detail. You'll notice that when you run the program, the window quickly flashes up and then disappears. This is because we are not processing any messages for the window. This will be dealt with in the next tutorial.

Please let me know of any comments you may have : Contact Me

Source Files : Visual Studio Dev-C++

< Tutorial 04 - Message Boxes Tutorial 06 - Message Loop >

Back to Top


All Rights Reserved, © Zeus Communication, Multimedia & Development 2004-2005

Read the Disclaimer

Links