C++ GUI

C++ GUI

Post by philG17 on Tue Aug 27, 2013 10:13 am
([msg=77067]see C++ GUI[/msg])

I just started a week ago learning C++. I have 1 year of experience in Java and I know some of the codes on how to make a simple window using it. I decided to switch on C++ because I heard that it is the best in creating software than Java. But only to find out, creating a GUI in C++ is very complicated that's why I'm going back to Java. My software engineering class is fast approaching so I need to be good in one language and I know that I don't have much time to learn C++. But still, I will continue learning it. What can you say?
philG17
New User
New User
 
Posts: 5
Joined: Tue Aug 20, 2013 11:40 pm
Blog: View Blog (0)


Re: C++ GUI

Post by centip3de on Tue Aug 27, 2013 11:52 am
([msg=77069]see Re: C++ GUI[/msg])

philG17 wrote:I just started a week ago learning C++. I have 1 year of experience in Java and I know some of the codes on how to make a simple window using it. I decided to switch on C++ because I heard that it is the best in creating software than Java. But only to find out, creating a GUI in C++ is very complicated that's why I'm going back to Java. My software engineering class is fast approaching so I need to be good in one language and I know that I don't have much time to learn C++. But still, I will continue learning it. What can you say?


First off, there's multiple different ways to make a GUI in C++, although most depend on the OS you're using. Some main ones are the Windows API directly, using QT, GTK, SDL, and wxWidgets. The complexity of each varies, as you might expect, although none of these are builtin libraries, like Java has. However both Java and C++ are even in complexity, with the exception that C++ is a quasi-superset of C, so it inherits some of C's complexity (though you don't have to use them (i.e. you can use 'new' instead of 'malloc'/'calloc'/'alloc')). It really comes down to what you want you want to use; if you want to use Java, then by all means use Java. Knowing C++ would certainly be beneficial in the long run, but (almost) everything that you can do with C++ can be done with Java and visa versa.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. -Rick Cook
User avatar
centip3de
Moderator
Moderator
 
Posts: 1449
Joined: Fri Aug 20, 2010 5:46 pm
Blog: View Blog (0)


Re: C++ GUI

Post by ghost107 on Tue Aug 27, 2013 1:02 pm
([msg=77071]see Re: C++ GUI[/msg])

For Java there is a a editor for swing using NetBeans or Eclipse. If you just stated C++ for few weeks it will be hard to make windows, because C++ is not quite like java, especially C++ has stuff that java does not have.
http://www.oracle.com/technetwork/java/ ... 42616.html

To make a window in C++(not talking the managed one, CLR/CLI):
In linux:
There is QT if you want the easy way, but if you want to do it natively XLib is library you need:
For example creating a window in XLib:
Code: Select all
//the Library you need
#include <X11/Xlib.h>
#include <stdio.h>

//your program Entry point
int main(){
   //Declaring the Variables
   Display *display;            // Driver to XServer
   Window window;                // Your window
   XEvent event;               // For Window Events like mouse or keyboard
   
   /* open connection with the server */
    display = XOpenDisplay(NULL);
    if (display == NULL){
      printf("cannot open display");
      return 1;
   }
   
   //Select your Screen
   screen = DefaultScreen(display);
   
   //Create a window of 500x500
   window = XCreateSimpleWindow(dis, RootWindow(dis, 0), 1, 1, 500, 500, 0, BlackPixel (dis, 0), BlackPixel(dis, 0));
   
   //Select type of the events we are interested in
   XSelectInput(display, window, ExposureMask | KeyPressMask);
   
   //map, show the window, and set the Window Name
   XMapWindow(display, window);
   XStoreName(display, window, szWindowName);
   
   bool bClose  = false;
   //Event Loop
   while(!bClose){
      XNextEvent(display, &event);
      //Main Event Switch
      Switch(event.type){
         case Expose: //draw or redraw the window
         //do stuff
         case KeyPress: //on keypress evenr
            bClose = true;
            break;
      }
   }
   
   //close the connection to the server
   XCloseDisplay(display);
   return 0;
}


On Windows:
If you want to make windows the Easy way there are library's like MFC(But requires license for VS Pro).

Using Win32 to create a window there are 6 steps:
1) Create and Fill a instance of WNDCLASSEX structure
2) Register the Class with RegisterClassEx
3)Create the Window with CreateWindowEx
4)make the window Visible with ShowWindow, and updateit with UpdateWindow
5) Enter the message Loop(Event Loop like in Xlib) with GetMessage or PeekMessage(This is usefull with DX)
6)Translate and Dispatch It(sends the message to window Procedure(Inside the Event loop in Xlib))

This is a basic tutorial for WN32 that shows how to make a WIN32 dialog window with some basic controlls and how to use them.

All windows API are in C, except for MFC, CLR, ATL, some say they are classes but if you look at the description they are structs.

Introduction
The main function in windows is a little different from the traditional int main()(from the console programming), the function will look something like this( http://msdn.microsoft.com/en-us/library ... 85%29.aspx ).
Code: Select all
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)

Win main it is not really necessary you could just simply use int main() if you want.

Creating a Window
Many types (like dialogs, controls, and other visual objects) are actual windows and sub-windows. The windows are created by the API function CreateWindowEx, to create any kind of window, be it the main window, or a control.
Code: Select all
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInt, HINSTANCE hpInt, LPSTR lpLine, int nShow){
         //Creating a window
         CreateWindowEx(
            WS_EX_CLIENTEDGE, // Window Type
        WC_DIALOG, //Class Name
        "MyWindow", // Window Title
        WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Window Proprieties
        0, // x Position on the Screen
        0, // y Position on the Screen
        width, // window Width
        height, //window Height
        NULL, // Parent window
        NULL,
        NULL, //Hint, handle to the previous window
        NULL
         );
                 //add await time or the window will close really fast
         return 0;
}

Or it could be added in the WM_CREATE(will talk later into the window Procedure)

Creating Controllers
The window handle is an HWND(usually we call it hWnd), the function CreateWindowEx returns the window handle which it creates. Without the handle we can not send messages to the child windows(controls).
HWND myDialogWindow = CreateWindowEx( arguments);
The code will look like( http://msdn.microsoft.com/en-us/library ... es_classes ):
Code: Select all
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInt, HINSTANCE hpInt, LPSTR lpLine, int nShow){
         //Creating a window
         HWND hMainWindow = CreateWindowEx(
          WS_EX_CLIENTEDGE, // Window Type
          WC_DIALOG, //Class Name
         "MyWindow", // Window Title
         WS_OVERLAPPEDWINDOW | WS_VISIBLE, // Window Proprieties
         0, // x Position on the Screen
         0, // y Position on the Screen
         width, // window Width
         height, //window Height
         NULL, // Parent window
         NULL,
         NULL, //Hint, handle to the previous window
         NULL
         );
         //Creating a button
         HWND hButton1 = CreateWindowEx(
                  0,
                  "BUTTON",// the class name, there are many classes "LABLE", EDIT", etc
                  "Buton",
                  BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
                  50,50,100,25,
                  hMainWindow ,// handle to the main parent window
                 NULL,NULL,NULL
          );

                 //add await time or the window will close really fast
          return 0;
}



The Window Procedure
The Window Procedure receives every event that happens on the main window(for example it could be user events, pressing a button, etc). The window procedure is called by the system when an event on the window happens, and the window is informed with a message.
Code: Select all
LRESULT WINAPI proc_name(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)


For a procedure to be attached to a window it needs to instantiate a class of type WNDCLASSEX and registered with RegisterClassEx. The function PostQuitMessage informs the main loop to break, any window procedure must not always return 0.
Code: Select all
#include <windows.h>
//the window procedure
LRESULT WINAPI wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    //if the message is WM_CLOSE
    if(message == WM_CLOSE) {
                 // when pressing the X on the window it will send WM_CLOSE to the window procedure
                 // with PostQuitMessage will exit the while loop
                 PostQuitMessage(0);
         }

         return 0;
}

//the entry point of the window
int APIENTRY WinMain(HINSTANCE hint, HINSTANCE hprev, LPSTR lpCmdLine, int iCmdShow){
    WNDCLASSEX wc; //the window class
    wc.cbSize    = sizeof(WNDCLASSEX);
    wc.style             = 0;
    wc.lpfnWndProc = wndProc; //the window procedure
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance         = hint;
    wc.hIcon             = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor   = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "WindowClass"; //the class name
    wc.hIconSm   = LoadIcon(NULL, IDI_APPLICATION);

    // registering the class
    if(!RegisterClassEx(&wc)){
                  //error it can not register the class
         }

         // creating a window
         HWND hwnd = CreateWindowEx( 0, "WindowClass","A dialog window",
                         WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                         400,100,200,200,
                         NULL,NULL,NULL,NULL
         );

    //making the window visible, showing the window
    ShowWindow(hwnd, true);

         //updating the window(this will call WM_PAINT)
         UpdateWindow(hwnd);

    //the window message loop
    MSG msg;
    while(GetMessage(&msg,NULL,0,0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
    }
    return 0;
}


Controllers types and how to use them
A good thing to know about controllers is that they are windows. As any other normal window they have a window procedure, window class, etc. which they are registered from the system. Anything you can do with a normal window you can do with a controller.

Messages:
Windows communicate using messages, when an event happens or when you want an control to do something, it will send a notification message. For standard controls the message will be WM_COMMAND and for common controls its WM_NOTIFY.

Messages can be send to a window using the API SendMessage with the use of GetDlgItem to access the data from that control, or you can use SendDlgItemMessage to do what SendMessage and GetDlgItem does.

The Edit Boxes
One of the most used controls are the windows environments is the edit control, that permits the user to insert, modify, copy,etc text.

We said earlier about the CreateWindowEx to create controls.
Code: Select all
#define IDC_EDIT 101 //used to identify a control, or you could use an enum

HWND hEdit = CreateWindowEx(
         0,
         "EDIT",// class name
         "Text Box",
         WS_VISIBLE | WS_CHILD,
         50,50,100,25,
         hwnd,
         (HMENU)IDC_EDIT, //the control identifier
          NULL,NULL
);


Accessing the information on the in the edit box it is made using the functions GetDlgItemText,si SetDlgItemText,
Code: Select all
GetWindowText, SetWindowText:
//hEdit is the control handle, and it can be accessed from anywhere
HWND hEdit = GetDlgItem( hwnd, IDC_EDIT);
GetWindowText(hEdit,buffer,255);
SetWindowText(hEdit,"New Message");

//or
GetDlgItemText(hwnd, IDC_EDIT, buffer, 255)
SetDlgItemText(hwnd, IDC_TEXT, "This is a string");

Notification Messages
When someone presses a button, the button sends the notification codes in type of WM_COMMAND to the parent window. for example a button control sends a notification code under the IDC_BUTTON every time the user presses the button.
Code: Select all
#define IDC_BUTON 102 //used for identifying a button
//...
CreateWindowEx(
    0,
    "BUTTON",// button class
    "Button",
    BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD,
    50,50,100,25,
    hwnd,
    (HMENU)IDC_BUTON,
    NULL,NULL
);


And in the Window procedure:
Code: Select all
LRESULT WINAPI wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    //you can change the if into a switch
    if(message == WM_COMMAND){
        switch(wParam){
                    case IDC_BUTON:
                                 MessageBox(hwnd,"Button Pressed","BTN WND",0);
                                 break;
                 }
                 return 0;
    }
}



Other Notifications:
WM_CREATE runs only once when the main window is created, in this notification you can create controls(Wrote above). WM_DESTROY same as WM_CREATE it runs once, when the window is destroyed, WM_PAINT it is called every time the function DispatchMessage is called.

WM_KEYDOWN and WM_KEYUP is called every time you press or release a keyboard key;
Code is from my Disertation Project
Code: Select all
switch(message) {
    case WM_KEYDOWN: // If we get a key down message, do stuff
       switch(wParam){
           case VK_ESCAPE: // If they push ESC, close the app
                 SendMessage(hwnd, WM_CLOSE, 0, 0);
                 break;
           case 'W':
           case VK_UP: // If they push up, move forward (Camera's +Z)
                 gCamera->move(Camera::eForward, MoveSpeed);
                 break;
           case 'S':
           case VK_DOWN: // If they push down, move backward (Camera's -Z)
                 gCamera->move(Camera::eBack, MoveSpeed);
                 break;
           case 'D':
           case VK_RIGHT: // If they push right, move right (Camera's +X)
                gCamera->move(Camera::eRight, MoveSpeed);
                break;
           case 'A':
           case VK_LEFT: // If they push left, move left (Camera's -X)
                gCamera->move(Camera::eLeft, MoveSpeed);
                break;
           case 'R':
                gCamera->reset(); // Recenter the camera
                break;
     }
     break;
}



WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, etc notifications are mouse events notifications or you could use WM_INPUT
Code: Select all
case WM_MOUSEMOVE:
{
         int xPos = GET_X_PARAM(lParam); //X absolute position
         int yPos = GET_Y_PARAM(lParam); //Y absolute position
         // ...
         break;
}


You can make really good windows forms fast using a resource editor(like ResEdit, WinASM, Etc).
ghost107
Poster
Poster
 
Posts: 132
Joined: Wed Jul 02, 2008 7:57 am
Blog: View Blog (0)



Return to C and C++

Who is online

Users browsing this forum: No registered users and 0 guests