C++ is indeed a language for programming Graphical User Interface(GUI) Applications
There ere are many API’s for making GUI applications in C++
Here are some.
1. WinAPI: (C based)(MFC is C++ based)
Its a great API and the best solution if you are windows programmer. First code will look a bit difficult, but later (after making few apps.) you will see its not so rusty. I like it, because you can do almost everything with it (in windows). The only bad thing is, that you cannot make applications for Linux with it.
Tutorial:
http://www.winprog.org/
2. Qt4 / Qt3 (C++ based)
This is a nice API, for making GUI applications. It works under Linux, Windows and Mac OS X. Its really easy to learn and use. But, until you dont buy licenced version, you will need to add tons of -dll s, to run your application. Qt compiler doesnt work in Vista. And, Qt4 API has a bit complicated way, to get buttons to work, if button holds some more complicated operations(actually you have to make your own SLOT’s).
Tutorial:
Check Google for help
3.GTK+ (C based)
Google might help you.
Tutorial:
Some examples:
WinAPI
Simple message box:
#include <windows.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK);
return 0;
}
Simple window:
#include <windows.h> const char g_szClassName[] = "myWindowClass";
// Step 4: the Window Procedure 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 wc; HWND hwnd; MSG Msg;
//Step 1: Registering the Window Class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0; wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// Step 2: Creating the Window hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);
// Step 3: The Message Loop while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg); DispatchMessage(&Msg);
}
return Msg.wParam;
}
QT4
Simple Message Box:
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButto *hello = new QPushButton("This is a simple button");
hello.resize(100, 30);
hello.show();
return app.exec();
}
Note: Use MsgBox for making message boxes
Simple Window:
#include <QApplication>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication app(argc, argv); QLabel *hello = new QLabel("This is a simple window");
hello.resize(100, 30); hello.show();
return app.exec();
}
GTK+
Simple window:
#include <gtk/gtk.h>
/* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */
static void hello( GtkWidget *widget, gpointer data )
{
g_print ("Hello World\n");
}
static gboolean delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
/* If you return FALSE in the "delete_event" signal handler, * GTK will emit the "destroy" signal. Returning TRUE means * you don't want the window to be destroyed. * This is useful for popping up 'are you sure you want to quit?' * type dialogs. */
g_print ("delete event occurred\n");
/* Change TRUE to FALSE and the main window will be destroyed with * a "delete_event". */
return TRUE;
}
/* Another callback */
static void destroy( GtkWidget *widget, gpointer data )
{
gtk_main_quit ();
}
int main( int argc, char *argv[] )
{
/* GtkWidget is the storage type for widgets */
GtkWidget *window; GtkWidget *button;
/* This is called in all GTK applications. Arguments are parsed * from the command line and are returned to the application. */
gtk_init (&argc, &argv);
/* create a new window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* When the window is given the "delete_event" signal (this is given * by the window manager, usually by the "close" option, or on the * titlebar), we ask it to call the delete_event () function * as defined above. The data passed to the callback * function is NULL and is ignored in the callback function. */ g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL); /* Here we connect the "destroy" event to a signal handler. * This event occurs when we call gtk_widget_destroy() on the window, * or if we return FALSE in the "delete_event" callback.
*/ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
/* Sets the border width of the window.
*/ gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Creates a new button with the label "Hello World". */
button = gtk_button_new_with_label ("Hello World");
/* When the button receives the "clicked" signal, it will call the * function hello() passing it NULL as its argument. The hello() * function is defined above. */
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (hello), NULL);
/* This will cause the window to be destroyed by calling * gtk_widget_destroy(window) when "clicked". Again, the destroy * signal could come from here, or the window manager. */
g_signal_connect_swapped (G_OBJECT (button), "clicked", G_CALLBACK (gtk_widget_destroy), G_OBJECT (window));
/* This packs the button into the window (a gtk container). */
gtk_container_add (GTK_CONTAINER (window), button);
/* The final step is to display this newly created widget. */
gtk_widget_show (button);
/* and the window */
gtk_widget_show (window);
/*All GTK applications must have a gtk_main(). Control ends here * and waits for an event to occur (like a key press or * mouse event). */
gtk_main (); return 0; }
Another alternative to C++ GUI Development:
In this section, we will build UI application using Windows Form provided by Visual Studio 2013.
In Project Setup stage for deploy, VS 2012 will be used. Express versions will work except the project setup for deployment.
The app is a very simple random number generator with two buttons (Generator/Reset), 7 Labels for the display of the random numbers with a PictureBox.
For WPF (Windows Presentation Foundation), please visit WPF & XAML.
Source:Â Dilbert
-
- Select Visual C++ CLR and CLR Empty Project
and type in RandomNumberGenerator for the project name. The, OK. - Project->Add New Item… .
Select UI under Visual C++.
Leave the Form name as given by default MyForm.h.
Then, click Add.
- Select Visual C++ CLR and CLR Empty Project
- We need to edit the MyForm.cpp file:
#include "MyForm.h" using namespace System; using namespace System::Windows::Forms; [STAThread] void Main(array<String^>^ args) { Application::EnableVisualStyles(); Application::SetCompatibleTextRenderingDefault(false); RandomNumberGenerator::MyForm form; Application::Run(%form); }
The System namespace provides functions to work with UI controls.
- At the right-mouse click on RandomNumberGenerator, we get the Properties window.
Configuration Properties->Linker->System
Select Windows (/SUBSYSTEM:WINDOWS) for SubSystem.
Advanced->Entry Point, type in Main.
The, hit OK. - Hit F5, then we will have to run result, the Form.
- Locate the ToolBox, and then expand the list of Common Controls.
Double-click its Label items to add it to our Form.
Do this seven times.
We need to add two Buttons and a PixtureBox.
Double-click those as well from the list. - Resize and rearrange the items. Rename the buttons and tile of the Form, then it should look like this:
- We can put the picture onto the PictureBox.
At a right mouse click, we get Choosing Picture….
Then, select the image file we want to use. - Let’s try if it works.
Run it (Hit F5).
- Let’s look at the file MyForm.h.
#pragma once namespace RandomNumberGenerator { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// /// Summary for MyForm /// public ref class MyForm : public System::Windows::Forms::Form { public: MyForm(void) { InitializeComponent(); // //TODO: Add the constructor code here // } ...
It begins with a pragma once directive.
To VS compiler, it means only open this file once during the compilation.
Also, as explained it before, the System namespace gives us functions to deal with UI controls.
The line public ref class MyForm : public System::Windows::Forms::Form defines a derived class named MyForm. The members of the class are the interface components. - To get a skeleton code for events, select the Generate button (button1), then type in button1_Click into for the Click under Action of the Properties window.
Then, VS will add additional code to MyForm.h for us:void InitializeComponent(void) { this->button1->Click += gcnew System::EventHandler(this, &MyForm;::button1_Click); ... #pragma endregion private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { }
Do the same for the Reset button (button2).
- Inside the bracket of Reset (button2), insert the following code to set the values to 0 when we click the button:
// Reset button private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) { // clear label fields this->label1->Text = "0"; this->label2->Text = "0"; this->label3->Text = "0"; this->label4->Text = "0"; this->label5->Text = "0"; this->label6->Text = "0"; this->label7->Text = "0"; // set button state this->button1->Enabled = true; this->button2->Enabled = false; }
Also, the fields should be set to 0 when we load the form. So, click the Label1, then set the Text to 0 under Properties window. Repeat the same to the reset of the labels. Note that we disabled the Reset button, and enabled the Generate button at the click.
- When the Generate is clicked, random numbers should be generated and displayed. We will put the code into the event handling function,
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e).// Generate button private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) { int num[7] = { 0 }; // seed srand((int) time(0)); // Randomize the array values. for (int i = 0; i < 7; i++) num[i] = (rand() % 99) + 1; // set the label text with random number this->label1->Text = Convert::ToString(num[0]); this->label2->Text = Convert::ToString(num[1]); this->label3->Text = Convert::ToString(num[2]); this->label4->Text = Convert::ToString(num[3]); this->label5->Text = Convert::ToString(num[4]); this->label6->Text = Convert::ToString(num[5]); this->label7->Text = Convert::ToString(num[6]); // change the button states. this->button1->Enabled = false; this->button2->Enabled = true; }
For more info on the random number, please visit Random Numbers in C++.
- Press F5 to run it again.
- Launch the Configuration Manager…, and select Release from Active solution configuration.
- We’ve done the following steps for the Debug version. Now, let’s do it for Release version.
At the right-mouse click on RandomNumberGenerator, we get the Properties window.
Configuration Properties->Linker->System
Select Windows (/SUBSYSTEM:WINDOWS) for SubSystem.
Advanced->Entry Point, type in Main.
The, hit OK. - To deploy the application, a Setup Project should be added to the solution to create the required files for installation.
- File->New. Launch a New Project dialog.
- From the New Project dialog, choose Other Project Types->Setup and Deployment.
We need to enter a name for the Setup Project.Click OK to add the project files to the Solution. Then we see the SetupProject in the Solution Explorer.
- From the Project Assistant window, we setup the properties of installation.
For example, the picture shows adding a Release folder to the install.
- After setup the install, we build the Setup Project. In this case, we do right click on the SetupRandomApp in the Solution Explorer
- Then, locate the setup.exe file and run. In this case, it’s in
C:\Users\KHyuck\Documents\Visual Studio 2012\
Projects\Random\SetupRandomApp\SetupRandomApp\Express\SingleImage\DiskImages\DISK1 - Go to the install directory, run the RandomNumberGenerator.exe.
Source: bogotobogo.com