Building Graphical User Interfaces (GUIs)
Using the Windows Application Programming Interface (API)


All of these examples assume that Microsoft Visual C++ 2010 or 2012 is the compiler being used.

Exercise 2: A simple window program

Now you are going to write a program which will create and display a simple window, register a callback function with the operating system, and wait for the operating sytem to pass it event messages. As simple as this program is it illustrates the basic functionality of ALL GUI programs you have ever seen or will ever write.

  1. If you have not already created the SimpleWindow project then click back on your browser and click the link Creating Projects in Visual Studio for GUI applications and follow the instructions for creating the project for exercise 2.

  2. Add a .cpp source file to the project. (Right click Source Files and select Add->New item. In the dialog box select .cpp file and give it a name like SimpleWinMain.cpp.

  3. Copy and paste the following text into the .cpp file changing John Doe to your name in step 2, Creating the Window:
    #include <windows.h>
    
    // Create the window name
    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 (Note: "Class" as used here means "Type" and 
        //                                        is not the same as a C++ class
    
        // Define the window characteristics
        wc.cbSize        = sizeof(WNDCLASSEX);              // Size in bytes of the struct
        wc.style         = 0;                               // Class style, usually set to 0
        wc.lpfnWndProc   = WndProc;                         // Call back function
        wc.cbClsExtra    = 0;                               // Extra data in memory, usually 0
        wc.cbWndExtra    = 0;                               // Extra data for win of this type, usually 0
        wc.hInstance     = hInstance;                       // Handle to this application
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // Large icon. Shown when user presses Alt-Tab
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);     // Cursor to use
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);        // Background color--White here.
        wc.lpszMenuName  = NULL;                            // Name of a menu resource. NULL if no menu bar.
        wc.lpszClassName = g_szClassName;                   // Name of the window class 
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION); // Small icon for title bar
    
        // Call the function to register the window class type with Windows OS
        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,        // Extended windows style.  This sets a sunken border
            g_szClassName,            // Name of the window class to use
            "A Simple Window App-John Doe", // Title to show in the title bar-Change John Doe to your name.
            WS_OVERLAPPEDWINDOW,    // Window style parameter.  There are quite a few. Look'em up.
            CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, // X,Y location on screen, width, height
            NULL, NULL, hInstance, NULL); // Parent handle, menu handle, app handle, window creation data
    
        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 (int)Msg.wParam; // Cast the WPARAM to an int value to keep the compiler happy
    }
    
  4. Compile and run the application. You should see a window like the one below appear. Click the close box in the upper right corner to close the window and terminate the application.

Adding Mouse Events to the Simple Window Program

You are now going to expand the simple window program to add the ability to handle mouse button down events. Add the following code to the switch statement in WndProc:

    case WM_LBUTTONDOWN :    // Handle left mouse button down
    {
        char sFileName[MAX_PATH];
        HINSTANCE hInstance = GetModuleHandle(NULL);
        GetModuleFileName(hInstance, sFileName, MAX_PATH);
        MessageBox(hwnd, sFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
    }
    break;
    case WM_MBUTTONDOWN :    // Handle middle mouse button down
        MessageBox(hwnd, "That was the middle button. Click the left one.", 
                       "Button Press Report", MB_OK | MB_ICONINFORMATION);
        break;
    case WM_RBUTTONDOWN :    // Handle right mouse button down
        MessageBox(hwnd, "That was the right button. Click the left one.", 
                       "Button Press Report", MB_OK | MB_ICONINFORMATION);
        break;