Creating a simple Windows application
In this tutorial we will create a basic Windows application.
This tutorial assumes that Visual Studio and DirectX SDK
are installed in your system (see previous tutorial for details).
To see all the tutorials that belong to this project click on the project name above.
If you are already familiar with the Win32 application development you can skip this tutorial and go to:
Creating a DirectX device, where we show how to
expend this simple Windows application to work with DirectX.
As you can see all this simple application does is presenting a window with a white background.
It is written with a native C++ and at this stage there is truly nothing DirectX about it. As it was already mentioned above our next step will be expending this simple Windows application with DirectX libraries and creating a DirectX device. But before we are ready to do that lets first examine the source code attached to this tutorial.
/*
CreateWindow.cpp
Tutorials and source code: www.danielloran.com
*/
#include <windows.h>
const char MAIN_WINDOW_TITLE[] = "© danielloran.com",
MAIN_WINDOW_CLASS_NAME[] = "myWindowClass";
const int MAIN_WINDOW_WIDTH = 340,
MAIN_WINDOW_HEIGHT = 240;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX w;
HWND hwnd;
MSG msg;
//Register window class
w.cbSize = sizeof(WNDCLASSEX);
w.style = 0;
w.lpfnWndProc = WndProc;
w.cbClsExtra = 0;
w.cbWndExtra = 0;
w.hInstance = hInstance;
w.hIcon = LoadIcon(NULL, IDI_APPLICATION); // large icon (Alt+Tab)
w.hCursor = LoadCursor(NULL, IDC_ARROW);
w.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
w.lpszMenuName = NULL;
w.lpszClassName = MAIN_WINDOW_CLASS_NAME;
w.hIconSm = LoadIcon(NULL, IDI_APPLICATION); // small icon (title bar)
if(!RegisterClassEx(&w)){
MessageBox(NULL, "RegisterClassEx() failed", "System error",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Create window
hwnd = CreateWindowEx(
NULL,
MAIN_WINDOW_CLASS_NAME,
MAIN_WINDOW_TITLE,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL){
MessageBox(NULL, "CreateWindowEx() failed", "System error",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Show window
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Message loop
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
If you already have some experience with developing applications for Windows, the source code above should be familiar to you. There are only 2 standard functions involved: WinMain() and WndProc(). The WinMain() function includes window definition and the main message loop. The WndProc() function processing the messages as long as application is running. As you probably already know Windows operating system is working with messages in order to make things happen. So to keep it simple, if you want something to happen you send a message. After the message has been received it is processed according to the logic you specify.
In this example only a very limited number of messages is being processed by the WndProc() function. Those messages are: WM_CLOSE and WM_DESTROY.
The WM_CLOSE message is sent when user closes the window. When it is received the window is destroyed by calling the DestroyWindow(hwnd) method.
The DestroyWindow() method also generates a WM_DESTROY message.
The WM_DESTROY message is causing the application to exit. This is achieved by calling the PostQuitMessage(0) method.
Inside the WinMain() function we use WNDCLASSEX to specify the kind of window we want to create.
In this project we use the extended window class. The hwnd is a handle to the window and msg is the message we
are going to send. We then register the window class and set all the desired parameters inclusive the window icon,
background color etc (please advise the Microsoft MSDN documentation for additional information about this subject).
We check if the window was registered succesfully, if not we show an error message in the MessageBox.
After the window was registered we create it by passing the title, widht and height among other parameters.
In the next step we show and update the window.
Finally we enter the message loop which is constantly checking if there are messages in the queue by calling the GetMessage() method. If yes those are translated and dispatched so they could be processed by the WndProc() function.
In the
next tutorial we will expend this source code to work with DirectX.