Ok, Let's get started.
Before moving onto GUI programming with C++ I expect you know quite a bit regarding C++ console programming. If not then go back. Don't
read this unless you are confident with your C++. You should at least know what are pointers, arrays, classes and how to create a switch()
statement.
NB: In order for you to compile the following programs, you are going to need a C++/C compiler. I won't go into the details of all of this. Go
and read a basic C++/C tutorial which will explain all you need to know about the basics.
>Your First glimpse at a Win32 application:
CODE
#include
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MessageBox (NULL, "Hello World" , "Tutorial", 0);
return 0;
}
Whoa! What is all that garbage. An explanation:
int WinMain is the windows equivalent of int main() in a console app. This is where the program starts when you compile your program.
WinMain() accepts the following parameters:
1. hInstance -Identifies the programs current instance.
2. hPrevInstance -Identifies the previous instance of the program. For a Win32 application, this parameter is always NULL.
3. lpCmdLine -Holds the command line arguments in a string. (Equivelant of argv[1] argv[2] in a console application)
4. nCmdShow -Value to be passed to the ShowWindow() API.
Notice the things like LPSTR in the parameter list. These are windows specific definitions. LPSTR is the same as char *. These things are
there to increase portability. You can use which ever one you prefer. Both char * and LPSTR will work.
MessageBox is a function that can be used to display a ...... MessageBox.
It accepts the following parameters:
1. hWnd -Identifies the owner of the MessageBox that will be created. If this is set to NULL then the MessageBox will have no owner
window.
2. lpText -This is the text that you want to be displayed in the MessageBox.
3. lpCaption -This is caption text of your MessageBox
4. uType -This parameter allows you to customize your MessageBox. Eg: display a warning or information icon.
Ok, now that that is done let's get down to REAL GUI programming.
>Creating a Simple Window:
Here is the source to a simple window:
CODE
#include
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static char sClassName[] = "MyClass";
static HINSTANCE zhInstance = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX WndClass;
HWND hwnd;
MSG Msg;
zhInstance = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = NULL;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = zhInstance;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = sClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&WndClass)) {
MessageBox(0, "Error Registering Class!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_STATICEDGE, sClassName, "db Tutorial", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT,
320, 240, NULL, NULL, zhInstance, NULL);
if(hwnd == NULL) {
MessageBox(0, "Error Creating Window!", "Error!", MB_ICONSTOP | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
switch(Message) {
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}
That does look confusing doesn't it? ;D. Well .... don't worry. You don't need to memorize all of this. Most people just create this once, then
save it as a seperate .cpp/.c file. Then, whenever they are creating a GUI application they just copy the code over to their application. This is
the skeleton of a GUI program.
Now lets get down to explaining all that stuff:
Windows programs unlike console applications are event driven. They remain idle until they recieve a message. Once they get a message,
they act on the message and then wait for the next message. When a windows application responds to a message it's called "Message
Handling".
As you can see I declared a prototype of my WndProc() function at the begining. It will be explained later.
Inside the WinMain() we see some strange new variables. Some of them include WndClass, hwnd and msg. Now, the msg struct contains
information from a threads message queue. The next thing we come to is when the hInstance is made global in the variable zhInstance. After
that we come to the defining of each of the WndClass settings:
1. cbSize -Holds the size of this structure in bytes, Always set this to the size of WndClassEx or WndClass.
2. style -The style of our window. For now just set it to NULL.
3. lpfnWndProc -This points to our Windows Callback Procedure ie: "WndProc".
4. cbClsExtra -The amount of extra data to be allocated for this class in memory. Set this to 0.
5. cbWndExtra -Amount of extra data to be allocated in memory per Window. Again, set this to 0
6. hInstance -The handle for the window instance.
7. hIcon -The icon that will be displayed when the users presses ALT+TAB. Don't worry too much about this at the moment.
8. hCursor -The cursor that will be used in our program. Again don't worry about this now.
9. hbrBackround -The brush that we will use to set the colour of our backround.
10. lpszMenuName -The name of the menu resource to use. We will not cover menu's in this tutorial, so set it to NULL.
11. lpszClassName -The name to identify the class with.
12. hIconSm -The small icon show in the top-left cornor of our program and in the taskbar.
Once we've filled in all that information, we need to "Register" our window class. So, we pass on our WndClass structure to RegisterClass or
RegisterClassEx.
Now, we need to actually create the window. We will use the CreateWindow() or CreateWindowEx() API to create our window. We store it in
hwnd which will later be passed onto ShowWindow(). CreateWindowEx() takes the following parameters:
dwExStyle -Tells it what style of window we want. We will use a plain static window.
lpClassName -Points to the classname we came up with earlier on.
lpWindowName -The titlebar text of our window.
dwStyle -The style of window we are creating.
x -The horizontal starting position of the window. Setting this to CW_USEDEFAULT will let windows pick a place.
y -The verticle starting position of our window. Again, Setting this to CW_USEDEFAULT will place the window randomly
nWidth -Width of our window.
nHeight -Height of our window.
hWndParent -The handle of the parent window. For now just set this to NULL since we don't have a parent.
hMenu -Identifies the menu for out window. Only applies if it's a child window.
hInstance -The hInstance of our window.
lpParam -Points to a value passed to the window through the CREATESTRUCT structure.
Now.... ShowWindow() sets our windows state. UpdateWindow() updates the client area of our window by sending a WM_PAINT message to
our window. The while() loop will set our program to loop until the WM_QUIT or WM_DESTROY message is recieved. TranslateMessage() will
translate virtual key messages into character messages. DispatchMessage() will dispatch a message to a windows procedure.
WH0000!!! I'm really tired now but wtf?
Let's get to the most important part of our program. Our CallBack Procedure. What this is, is a function with a beeeeg giant switch()
statement to switch of what each message should do. Our CallBack takes the following parameters:
hwnd -Identifies our window.
uMsg -Specified the message.
wParam -Specifies the aditional message information. The contents of this value depends on the value of the uMsg.
lParam -Specifies additonal message info. Again the contents of this value depends on uMsg.
Now, in our switch() statement we see a WM_CLOSE. This message tells us if our user clicked the 'X' button in our program or they hit
ALT+F4. By using WM_CLOSE we can prompt the user if he wants to save his current work or whatever.
OK FOLKS.... thats it. A Basic C++ GUI tutorial. Maybe if i'm bored one day, I will post a more advanced tutorial covering text, buttons and other l33t things.
Before you leave, please promote this article with your favorite bookmarking site using the Share/save button! AND DO please give your valuable comment