Event driven Windows app

Windows apps are event driven apps. An event can be an external or internal input to an app. Event driven apps run a message loop, which parses incoming events and then calls appropriate functions corresponding to that event. Code::Blocks default code generated by Win32 GUI project wizard generates a boilerplate code of an event driven app.

In order to understand event driven programming we shall be using following example to learn and understand it. We shall be using native Win32 API for this example. Win32 API is the base of several toolkits. Thus we should have an understanding of it in order to understand other toolkits.

Let's create another GUI app and name it App10. Replace wizard generated code with the following code. Also enable Unicode support as per the steps laid out in the previous example. As the code snippet is large we'll understand and paste it in editor window in several steps.

The following code snippet shows the header declaration, global variable declaration, and declaration of callback function:

#include <windows.h>
#define ID_BTN_CLICK_ME 100
// This function is called by the Windows function DispatchMessage()
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

// Make the class name into a global variable
TCHAR szClassName[ ] = TEXT("CodeBlocksWindowsApp");

In the following snippet we'll define the WinMain() function. We will define an object of WNDCLASSEX structure inside the WinMain() function. This structure takes several inputs. With wincl.lpfnWndProc we have assigned a callback function WindowProcedure() to the wincl object. This instructs app to call that function for event processing. Finally the wincl object will get registered with the RegisterClassEx() function. Once the object is registered successfully we create a window of that class using the CreateWindowEx() function.

We will display newly created window using the ShowWindow() function. After the window is displayed we will run an event processing loop using the GetMessage() function inside a while loop. All incoming events are then sent to the WindowProcedure() function by DispatchMessage() function.

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
    HWND hwnd;    // This is the handle for our window
    MSG messages; // Here messages to the application are saved
    WNDCLASSEX wincl; //Data structure for the windowclass

    // The Window structure
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;  // Callback function
    wincl.style = CS_DBLCLKS; // Catch double-clicks
    wincl.cbSize = sizeof (WNDCLASSEX);

    // Use default icon and mouse-pointer
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;  /* No menu */
    wincl.cbClsExtra = 0;  // No extra bytes after the window class
    wincl.cbWndExtra = 0;  // structure or the window instance
    // Use Windows's default colour as the background of the window
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    // Register the window class, and if it fails quit the program
    if (!RegisterClassEx (&wincl))
        return 0;

    // The class is registered, let's create the window
    hwnd = CreateWindowEx (
           0,            // Extended possibilites for variation
           szClassName,         // Classname
           TEXT("App for Windows"), // Title Text
           WS_OVERLAPPEDWINDOW, // default window
           CW_USEDEFAULT,  // Windows decides the position
           CW_USEDEFAULT,  // where the window ends up on the screen
           300,            // The programs width
           250,            // and height in pixels
           HWND_DESKTOP,   // The window is a child-window to desktop
           NULL,           // No menu
           hThisInstance,  // Program Instance handler
           NULL            // No Window Creation data
           );

    // Make the window visible on the screen
    ShowWindow (hwnd, nCmdShow);

    // Run the message loop. It will run until GetMessage() returns 0
    while (GetMessage (&messages, NULL, 0, 0))
    {
        // Translate virtual-key messages into character messages
        TranslateMessage(&messages);
        // Send message to WindowProcedure
        DispatchMessage(&messages);
    }

    // Return value of PostQuitMessage()
    return messages.wParam;
}

The WM_CREATE event is sent out by Windows OS when a window is being created. We will then create a button using the CreateWindow() function.

We shall be processing button press by processing the WM_COMMAND event in the WindowProcedure() function. We will then display a message box whenever this button is clicked.

Finally we will be processing the WM_DESTROY event, which will be issued whenever window is being destroyed. A return value of 0 will be posted with the PostQuitMessage() function emitting a WM_QUIT event to the message queue.

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message) // handle the messages
    {
        case WM_CREATE:
            CreateWindow(TEXT("button"), TEXT("Click Me!"),                     WS_VISIBLE | WS_CHILD, 20, 50, 80, 25, hwnd, (HMENU) ID_BTN_CLICK_ME, NULL, NULL);
            break;
        case WM_COMMAND:
            if (LOWORD(wParam) == ID_BTN_CLICK_ME) {
                MessageBox(hwnd, TEXT("Hello World!"),             TEXT("Information"), MB_OK | MB_ICONINFORMATION);
            }
            break;
        case WM_DESTROY:
            PostQuitMessage (0); // send a WM_QUIT to the message queue
            break;
        default:  // for messages that we don't deal with
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

This completes our Windows app. Hit F9 key (an alternative to clicking on the build and then run icon in build toolbar) to build and run this app. Following screenshot will be presented:

Event driven Windows app

Advantages of Win32 API:

  • Produces smaller executable size
  • Produces faster code due to less overhead

Disadvantages of Win32 API:

  • Requires longer development time due larger amount of code to be written
  • Minimal set of GUI controls (for example, a text box, button, and so on) are available to developer

To solve this problem, GUI toolkit was developed. The GUI toolkit simplifies development process allowing reuse of code and a smaller code base. It also contains complex GUI control (for example, rich text control, HTML control, and so on).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.17.12