Post: [C++] Win32 WINAPI Make a GUI! #1 - Blank Window
02-23-2014, 12:23 PM #1
(adsbygoogle = window.adsbygoogle || []).push({}); Hey guys!
Today I will be teaching on how to use the Win32 WINAPI in C++ to create a GUI...

Ever wondered how so many programs are made in C++ and have a GUI? ... Because of this :P...

In C++ you can also NOT use the CommControls(); (which we will talk about a few tutorials ahead) and design your own... so let´s start...

First ..

Q : Can´t I simply drag and drop stuff like in C# , VB... ?
A : NO! C++ Does not have a designer, it is a 'professional' language and does not belong to any framework...

In this tutorial we will just create a blank window ... next tutorial we will add some controls and learn how to use them.

So let´s start!

Create a Win32 Project (or WinProject) , make sure its a Windows Application and that is setted as 'Empty Project'

Head over to your Source Files and add a .cpp file.. name it whatever you want!

In your new file include the Windows.h!

    #include <Windows.h>


That contains nearly anything you need for a basic Win32 C++ GUI Programming...

Okay..

Now you are going to name your program class!

    LPCWSTR g_szClassName = L"MainWindow_Class";


Again you can name it whatever you want!


Okay, now you want to create your function that handles the program close and destroy (and in future will handle buttons and stuff..)

First here is just the whole function.... then I will explain it further

    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;
}


Okay so lets start.... well the actual function is just how it is! Its just how it is defined...

so

    switch (msg) //This 'handles' anything that we will be later recieving from the WinMain!
{
case WM_CLOSE: //if we close the window
DestroyWindow(hwnd); // destroy it!
break;
case WM_DESTROY: //if we destroy the window
PostQuitMessage(0); //tell the computer that the program has quitted
break;
default: //returning to default
return DefWindowProc(hwnd, msg, wParam, lParam); //return the default window process
}
return 0; //out of the switch return 0 ( null )


Okay!
Now its the actual 'GUI' Designing... its not really designing cuz it will be blank :P

So here is the function and I will later explain it

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG msg;
HWND hwnd;

ZeroMemory(&wc, sizeof(&wc));

wc.style = 0;
wc.lpszClassName = g_szClassName;
wc.lpszMenuName = NULL;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hIconSm = LoadIcon(NULL, IDC_ICON);
wc.hIcon = LoadIcon(NULL, IDC_ICON);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.cbWndExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;

if (!RegisterClassEx(&wc))
{
LPCWSTR Error01 = L"Could not register class!";
LPCWSTR Error01_Caption = L"Error";
MessageBox(NULL, Error01, Error01_Caption, MB_OK | MB_ICONERROR);
}

LPCWSTR WindowTitle = L"EXAMPLE WINDOW!";

hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, WindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL);

if (hwnd == NULL)
{
LPCWSTR Error02 = L"Could not create Window!";
LPCWSTR Error02_Caption = L"Error";
MessageBox(NULL, Error02 , Error02_Caption , MB_OK | MB_ICONERROR);
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}


Okay! So now I will comment it out...

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG msg;
HWND hwnd;

ZeroMemory(&wc, sizeof(&wc)); //We are cleaning the memory so we know we are really starting from scratch

wc.style = 0; //the style of the window is null (default)
wc.lpszClassName = g_szClassName; //the class of the window we are setting it as g_szClassName
wc.lpszMenuName = NULL; //we really dont have a menu name ...
wc.lpfnWndProc = WndProc; //In here we are setting the process which will later recieve the messages
wc.hInstance = hInstance; //defining the hInstance
wc.hIconSm = LoadIcon(NULL, IDC_ICON); //defining the icon shown in the taskbar
wc.hIcon = LoadIcon(NULL, IDC_ICON); //defining the actual icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //defining the program cursor
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); In here we are just setting the bg as white
wc.cbWndExtra = 0; // NULL
wc.cbSize = sizeof(WNDCLASSEX); // This im really not sure
wc.cbClsExtra = 0; // NULL

if (!RegisterClassEx(&wc))
{
LPCWSTR Error01 = L"Could not register class!";
LPCWSTR Error01_Caption = L"Error";
MessageBox(NULL, Error01, Error01_Caption, MB_OK | MB_ICONERROR);
} //Attempt to register our class.. if it fails then tells us it failed!

LPCWSTR WindowTitle = L"EXAMPLE WINDOW!"; //our title

hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, WindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL); //creating our window into the hwnd

if (hwnd == NULL)
{
LPCWSTR Error02 = L"Could not create Window!";
LPCWSTR Error02_Caption = L"Error";
MessageBox(NULL, Error02 , Error02_Caption , MB_OK | MB_ICONERROR);
} //if window creation failed (hwnd is empty) tell us so!

ShowWindow(hwnd, nCmdShow); //Show the window
UpdateWindow(hwnd); // Update the window with the elements (none in this case)

while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} //keep translating and sending messages to our WndProc func

return msg.wParam; //returning the msg wParam
}


Okay! So thats it.. very simple right??

I hope you guys have enjoyed and now understand the basics of WIN32 C++ programming...

FULL Source : You must login or register to view this content.

Video :

The following 3 users say thank you to MW2TopTenWORLD for this useful post:

#Dragoss, iNDMx, Shark
03-22-2016, 10:57 PM #2
Jim Halpert
Bounty hunter
Originally posted by MW2TopTenWORLD View Post
Hey guys!
Today I will be teaching on how to use the Win32 WINAPI in C++ to create a GUI...

Ever wondered how so many programs are made in C++ and have a GUI? ... Because of this :P...

In C++ you can also NOT use the CommControls(); (which we will talk about a few tutorials ahead) and design your own... so let´s start...

First ..

Q : Can´t I simply drag and drop stuff like in C# , VB... ?
A : NO! C++ Does not have a designer, it is a 'professional' language and does not belong to any framework...

In this tutorial we will just create a blank window ... next tutorial we will add some controls and learn how to use them.

So let´s start!

Create a Win32 Project (or WinProject) , make sure its a Windows Application and that is setted as 'Empty Project'

Head over to your Source Files and add a .cpp file.. name it whatever you want!

In your new file include the Windows.h!

    #include <Windows.h>


That contains nearly anything you need for a basic Win32 C++ GUI Programming...

Okay..

Now you are going to name your program class!

    LPCWSTR g_szClassName = L"MainWindow_Class";


Again you can name it whatever you want!


Okay, now you want to create your function that handles the program close and destroy (and in future will handle buttons and stuff..)

First here is just the whole function.... then I will explain it further

    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;
}


Okay so lets start.... well the actual function is just how it is! Its just how it is defined...

so

    switch (msg) //This 'handles' anything that we will be later recieving from the WinMain!
{
case WM_CLOSE: //if we close the window
DestroyWindow(hwnd); // destroy it!
break;
case WM_DESTROY: //if we destroy the window
PostQuitMessage(0); //tell the computer that the program has quitted
break;
default: //returning to default
return DefWindowProc(hwnd, msg, wParam, lParam); //return the default window process
}
return 0; //out of the switch return 0 ( null )


Okay!
Now its the actual 'GUI' Designing... its not really designing cuz it will be blank :P

So here is the function and I will later explain it

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG msg;
HWND hwnd;

ZeroMemory(&wc, sizeof(&wc));

wc.style = 0;
wc.lpszClassName = g_szClassName;
wc.lpszMenuName = NULL;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hIconSm = LoadIcon(NULL, IDC_ICON);
wc.hIcon = LoadIcon(NULL, IDC_ICON);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.cbWndExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbClsExtra = 0;

if (!RegisterClassEx(&wc))
{
LPCWSTR Error01 = L"Could not register class!";
LPCWSTR Error01_Caption = L"Error";
MessageBox(NULL, Error01, Error01_Caption, MB_OK | MB_ICONERROR);
}

LPCWSTR WindowTitle = L"EXAMPLE WINDOW!";

hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, WindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL);

if (hwnd == NULL)
{
LPCWSTR Error02 = L"Could not create Window!";
LPCWSTR Error02_Caption = L"Error";
MessageBox(NULL, Error02 , Error02_Caption , MB_OK | MB_ICONERROR);
}

ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}


Okay! So now I will comment it out...

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG msg;
HWND hwnd;

ZeroMemory(&wc, sizeof(&wc)); //We are cleaning the memory so we know we are really starting from scratch

wc.style = 0; //the style of the window is null (default)
wc.lpszClassName = g_szClassName; //the class of the window we are setting it as g_szClassName
wc.lpszMenuName = NULL; //we really dont have a menu name ...
wc.lpfnWndProc = WndProc; //In here we are setting the process which will later recieve the messages
wc.hInstance = hInstance; //defining the hInstance
wc.hIconSm = LoadIcon(NULL, IDC_ICON); //defining the icon shown in the taskbar
wc.hIcon = LoadIcon(NULL, IDC_ICON); //defining the actual icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); //defining the program cursor
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); In here we are just setting the bg as white
wc.cbWndExtra = 0; // NULL
wc.cbSize = sizeof(WNDCLASSEX); // This im really not sure
wc.cbClsExtra = 0; // NULL

if (!RegisterClassEx(&wc))
{
LPCWSTR Error01 = L"Could not register class!";
LPCWSTR Error01_Caption = L"Error";
MessageBox(NULL, Error01, Error01_Caption, MB_OK | MB_ICONERROR);
} //Attempt to register our class.. if it fails then tells us it failed!

LPCWSTR WindowTitle = L"EXAMPLE WINDOW!"; //our title

hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, WindowTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInstance, NULL); //creating our window into the hwnd

if (hwnd == NULL)
{
LPCWSTR Error02 = L"Could not create Window!";
LPCWSTR Error02_Caption = L"Error";
MessageBox(NULL, Error02 , Error02_Caption , MB_OK | MB_ICONERROR);
} //if window creation failed (hwnd is empty) tell us so!

ShowWindow(hwnd, nCmdShow); //Show the window
UpdateWindow(hwnd); // Update the window with the elements (none in this case)

while(GetMessage(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} //keep translating and sending messages to our WndProc func

return msg.wParam; //returning the msg wParam
}


Okay! So thats it.. very simple right??

I hope you guys have enjoyed and now understand the basics of WIN32 C++ programming...

FULL Source : You must login or register to view this content.

Video :


Why not use Qt? It certainly fixes the question "Can´t I simply drag and drop stuff like in C# , VB... ?" in the beginning of the thread. It is also platform-independent.

Copyright © 2024, NextGenUpdate.
All Rights Reserved.

Gray NextGenUpdate Logo