|
In this part you will learn to create a complete Win32 application. As I said in the previous tutorial (Beginning Win32 SDK Programming) a Win32 application contains a Message Processor function which will process all the events that your window receives. In this tutorial we are going to create a simple message processor function.
Create a Win32 SDK project and add this code:
#include <windows.h>
LRESULT CALLBACK WndProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam){
switch(message){
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wParam,lParam);
}
INT WINAPI WinMain( HINSTANCE , HINSTANCE , LPSTR , INT ){
// Create A Window Class Structure
WNDCLASSEX wc;
wc.cbClsExtra = 0;
wc.cbSize = sizeof(wc);
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = NULL;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "X3D";
wc.lpszMenuName = NULL;
wc.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC;
// Register Window Class
RegisterClassEx(&wc);
// Create Window
HWND hWnd = CreateWindowEx(0,
"X3D", "X3D Win32 Tutorial 1",
WS_OVERLAPPEDWINDOW, 100,100,400,400,
NULL,NULL,wc.hInstance,0);
ShowWindow(hWnd,SW_SHOW);
// Message Loop
MSG msg;
while(true){
if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE)){
if(msg.message==WM_QUIT)break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return 0;
} |
First we defined a function called WndProc which is in fact our message processor function.
LRESULT CALLBACK WndProc( HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam){
switch(message){
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd,message,wParam,lParam);
} |
This function takes four parameters, first one is a handle to the window which
the message is sent to and the second one is a positive integer specifying the message name. Two last parameters, wParam and lParam are the message parameters. For example if you click on the window, message will be equal to WM_LBUTTONDOWN, wParam specifies whether a control key like Shift, Ctrl or Alt is pressed or not, and lParam specifies the mouse cursor position. You can find the meaning of the other values for all the events by referring to MSDN. Here we just processed the WM_CLOSE message which will is sent when application window is closing. After receiving this message we called PostQuitMessage() function which sends a WM_QUIT message to the window and causes the program to be terminated. At the end of WndProc, there is call to DefWindowProc() function which is a default message processor that handles a lot of other message which we don't care about.
// Create A Window Class Structure
WNDCLASSEX wc;
wc.cbClsExtra = 0;
wc.cbSize = sizeof(wc);
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = NULL;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hInstance = GetModuleHandle(NULL);
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "X3D";
wc.lpszMenuName = NULL;
wc.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC; |
Here we explain about some data members of WNDCLASSEX structure.
|
cbSize
|
This parameter must always set to be equal to structure size
|
|
hbrBackground
|
This parameter specifies the brush which fills the window background. You can use
GREEN_BRUSH, WHITE_BRUSH, and etc.
|
|
hInstance
|
The Handle of the application instance.
|
|
lpfnWndProc
|
This is a pointer to the message processor function. You can set this to your own
message handler or the default handler which is called DefWindowProc.
|
|
lpszClassName
|
The name of window class, you can choose a desired name. Later you can use this name to refer to the class.
|
|
hIcon
|
Handle to an icon which will be set as the application icon.
|
|
hIconSm
|
Handle to a small icon which will be showed on the task bar.
|
|
hCursor
|
Handle to a loaded cursor resource.
|
|
lpszMenuName
|
Specifies the menu wich will be associated to the window.
|
Three parameters (style, cbWndExtra, cbClsExtra) aren't explained here because of
complexity that you don't need them at current time. After filling window class structure RegisterClassEx() function registers the class in windows registery, and then CreateWindowEx() function creates a window.
// Create Window
HWND hWnd = CreateWindowEx(0,
"X3D", "X3D Win32 Tutorial 1",
WS_OVERLAPPEDWINDOW, 100,100,400,400,
NULL,NULL,wc.hInstance,0); |
The first parameter which we pass to this function is dwExStyle that specifies extended window styles and isn't used here. Second parameter which is so important is the name of window class. Third parameter is the window title. Next parameter specifies the window style which you can pass these values instead : WS_POPUP or WS_OVERLAPPED. Two next parameters specifiy coordinates of top-left corner of the window and two next parameters are window width and height. Ninth parameter which we set to NULL is a handle to the parent window (This value shows that this window has no parents). Next parameter specifies the menu which is attached to the window (We didn't use it here). Next parameter is a handle to the application instance and last parameter is a data which is sent to the window with WM_CREATE message.
OK, Next part which seems like a stupid forever loop is in fact our application
control center.
// Message Loop
MSG msg;
while(true){
if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE)){
if(msg.message==WM_QUIT)break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} |
We get new messages from windows by PeekMessage() function, TranslateMessage()
function converts virtual keys to the actual characters and finally DispatchMessage() Sends the message to message processor function which is WndProc() here. In the middle we checked for WM_QUIT and terminate the program just after receving this message.
Now It's time to compile and run the code, try to change values and see the result
and of course always refer to MSDN to find exact functions descriptions. If you have any question feel free to contact me. Finally I hope that this tutorial could help you.
Good Luck |