Introduction to Windows Win32 Basics

What is Win32?

The Win32 API (Application Programming Interface) is a set of functions and structures that allow software to interact with the Microsoft Windows operating system. It forms the foundation for most graphical applications on Windows, providing access to core functionalities like window management, memory management, process and thread control, file I/O, and more.

Understanding Win32 is crucial for any developer looking to create native Windows applications or dive deep into how Windows applications operate.

Key Concepts

Windows and Messages

At its heart, Win32 is a message-driven system. Every application creates windows, and these windows receive messages from the operating system and other applications. These messages can represent user input (like mouse clicks or keystrokes), system events (like window resizing), or notifications from other parts of the system.

The core loop for a Win32 application involves:

Window Procedure (WndProc)

The WndProc is a callback function that you, the developer, write. It's responsible for handling all messages sent to a specific window. It receives a window handle (HWND), a message identifier (UINT), and two message parameters (WPARAM and LPARAM).

Tip: The DefWindowProc function is essential. If your WndProc doesn't handle a particular message, you should pass it to DefWindowProc to ensure default behavior is applied.

Handles (Hxxx)

Win32 heavily relies on handles. A handle is an opaque identifier (usually an integer) that refers to an object managed by the operating system. You don't directly manipulate the object; instead, you use its handle to tell the OS what you want to do with it. Common handles include:

A Minimal Win32 "Hello, World!" Structure

Here's a simplified C/C++ code structure that demonstrates the basic Win32 application skeleton.


#include <windows.h>

// Forward declaration of the Window Procedure
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

// Entry point of the application
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // 1. Register the window class
    const char CLASS_NAME[] = "SampleWindowClass";

    WNDCLASS wc = { };

    wc.lpfnWndProc   = WndProc;
    wc.hInstance     = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // Default window background
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); // Default cursor
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // Default icon

    RegisterClass(&wc);

    // 2. Create the window
    HWND hwnd = CreateWindowEx(
        0,                              // Optional window styles
        CLASS_NAME,                     // Window class name
        "Win32 Basics Example",         // Window title
        WS_OVERLAPPEDWINDOW,            // Window style

        // Size and position
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,       // Parent window
        NULL,       // Menu
        hInstance,  // Instance handle
        NULL        // Additional application data
    );

    if (hwnd == NULL) {
        return 0;
    }

    // 3. Show the window
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    // 4. The Message Loop
    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

// 5. The Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_DESTROY:
            PostQuitMessage(0); // Signal the application to exit
            return 0;

        case WM_PAINT: { // Handle window repainting
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);

            // Simple text drawing
            RECT rect;
            GetClientRect(hwnd, &rect);
            DrawText(hdc, "Hello, Win32!", -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

            EndPaint(hwnd, &ps);
        }
        return 0;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam); // Default message handling
}

            

Note: This is a bare-bones example. Real-world applications involve much more complex message handling, error checking, and resource management.

Next Steps

This page provides a foundational understanding. To explore further, consider looking into:

The Win32 API is vast, but mastering these basic concepts will set you on a solid path to developing robust Windows applications.