Neural Architecture Hub
C & C++

Windows.h (Win32 API)

C and C++ Windows programming quick reference from message boxes and basic windows to multi-threading, file I/O, custom drawing, and COM basics.

📦 1. Including the Header

#include <windows.h>  // Main Win32 API header — includes everything
#include <stdio.h>    // Standard I/O (optional but useful)

🟢 BEGINNER

2. Hello World Message Box

#include <windows.h>

int main() {
    // MessageBoxA = ASCII version, MessageBoxW = Wide (Unicode)
    // Args: (parent window, message, title, buttons/icon flags)
    MessageBoxA(NULL, "Hello, World!", "My First Window", MB_OK | MB_ICONINFORMATION);
    return 0;
}

3. Common Data Types

// Win32 defines its own types — always prefer these in Win32 code
BOOL   flag   = TRUE;       // Basically int (TRUE=1, FALSE=0)
DWORD  val    = 0xFFFFFFFF; // Unsigned 32-bit integer
WORD   small  = 0xFFFF;     // Unsigned 16-bit integer
BYTE   b      = 0xFF;       // Unsigned 8-bit integer
HANDLE h      = NULL;       // Generic opaque object handle
HWND   hwnd   = NULL;       // Handle to a Window
HINSTANCE hInst = NULL;     // Handle to a module/instance
LPSTR  str    = "hello";    // Long Pointer to char (ASCII string)
LPCSTR cstr   = "const";    // Long Pointer to const char
LPWSTR wstr   = L"wide";    // Long Pointer to wide char (Unicode)

4. String Operations (Win32 Style)

TCHAR buf[256];

// lstrlen — length of a Win32 string
int len = lstrlen(TEXT("Hello"));  // TEXT() macro handles A/W automatically

// lstrcpy — copy a string
lstrcpy(buf, TEXT("Hello Win32"));

// lstrcmp — compare strings (0 = equal)
if (lstrcmp(buf, TEXT("Hello Win32")) == 0) {
    // Strings are equal
}

// wsprintf — safe sprintf for Win32 (no floats)
wsprintf(buf, TEXT("Value: %d"), 42);

5. Getting Last Error

HANDLE h = CreateFile(TEXT("missing.txt"), GENERIC_READ, 0, NULL,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (h == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError(); // Retrieve the last Win32 error code
    // Common codes: 2 = FILE_NOT_FOUND, 5 = ACCESS_DENIED
    printf("Error: %lu\\n", err);
}

6. Console Output

// Attach or allocate a console window
AllocConsole();  // Creates a new console for the process

// Write to console via standard handle
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); // Get stdout handle
DWORD written;
WriteConsole(hOut, TEXT("Hello Console\\n"), 14, &written, NULL);

🟡 INTERMEDIATE

7. Creating a Basic Window (WinMain)

#include <windows.h>

// Window Procedure — handles messages sent to the window
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_DESTROY:
            PostQuitMessage(0); // Signal the message loop to exit
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam); // Default handling
    }
    return 0;
}

// Entry point for GUI apps (instead of main)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow) {
    // Step 1: Register the window class
    WNDCLASS wc = {0};
    wc.lpfnWndProc   = WndProc;           // Assign our message handler
    wc.hInstance     = hInstance;
    wc.lpszClassName = TEXT("MyWindow");
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // White background
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); // Standard arrow cursor
    RegisterClass(&wc);

    // Step 2: Create the window
    HWND hwnd = CreateWindow(
        TEXT("MyWindow"),     // Class name (must match RegisterClass)
        TEXT("My App"),       // Window title
        WS_OVERLAPPEDWINDOW,  // Style flags (title bar, borders, etc.)
        100, 100,             // X, Y position
        800, 600,             // Width, Height
        NULL, NULL, hInstance, NULL
    );

    ShowWindow(hwnd, nShow);   // Make it visible
    UpdateWindow(hwnd);        // Force a WM_PAINT

    // Step 3: Message loop — keeps app alive and processes events
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg); // Translate virtual keys to WM_CHAR
        DispatchMessage(&msg);  // Send message to WndProc
    }
    return (int)msg.wParam;
}

8. Handling Common Messages

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE:
            // Called once when the window is first created — good for init
            break;

        case WM_PAINT: {
            // Called when window needs to be redrawn
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps); // Get device context for painting
            TextOut(hdc, 10, 10, TEXT("Hello from WM_PAINT"), 19);
            EndPaint(hwnd, &ps); // Always pair with BeginPaint
            break;
        }

        case WM_KEYDOWN:
            // wParam holds the virtual key code (e.g., VK_ESCAPE, VK_RETURN)
            if (wParam == VK_ESCAPE) PostQuitMessage(0);
            break;

        case WM_LBUTTONDOWN:
            // Mouse left button clicked
            // LOWORD(lParam) = X, HIWORD(lParam) = Y
            MessageBox(hwnd, TEXT("Clicked!"), TEXT("Mouse"), MB_OK);
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

9. Controls (Button, Edit, Static)

// Create controls inside WM_CREATE using CreateWindow
case WM_CREATE: {
    // Button control
    CreateWindow(TEXT("BUTTON"), TEXT("Click Me"),
        WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
        50, 50, 120, 30,     // x, y, width, height
        hwnd, (HMENU)1,      // Parent, control ID
        hInstance, NULL);

    // Single-line text input
    CreateWindow(TEXT("EDIT"), TEXT(""),
        WS_VISIBLE | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL,
        50, 100, 200, 25,
        hwnd, (HMENU)2, hInstance, NULL);

    // Static label
    CreateWindow(TEXT("STATIC"), TEXT("Enter text:"),
        WS_VISIBLE | WS_CHILD,
        50, 80, 100, 20,
        hwnd, (HMENU)3, hInstance, NULL);
    break;
}

// Handle button click via WM_COMMAND
case WM_COMMAND:
    if (LOWORD(wParam) == 1) {  // Control ID 1 = Button
        // BN_CLICKED is in HIWORD(wParam), but for buttons just match ID
        TCHAR buf[256];
        GetDlgItemText(hwnd, 2, buf, 256); // Read text from edit control ID 2
        MessageBox(hwnd, buf, TEXT("You typed:"), MB_OK);
    }
    break;

10. File I/O (Win32 Style)

// --- Write to a file ---
HANDLE hFile = CreateFile(
    TEXT("output.txt"),      // Filename
    GENERIC_WRITE,           // Access mode
    0,                       // No sharing
    NULL,                    // Default security
    CREATE_ALWAYS,           // Overwrite if exists
    FILE_ATTRIBUTE_NORMAL,   // Normal file
    NULL
);

if (hFile != INVALID_HANDLE_VALUE) {
    const char* data = "Hello File!";
    DWORD written;
    WriteFile(hFile, data, lstrlenA(data), &written, NULL);
    CloseHandle(hFile); // Always close handles when done
}

// --- Read from a file ---
hFile = CreateFile(TEXT("output.txt"), GENERIC_READ, FILE_SHARE_READ,
                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile != INVALID_HANDLE_VALUE) {
    char buf[256] = {0};
    DWORD bytesRead;
    ReadFile(hFile, buf, sizeof(buf) - 1, &bytesRead, NULL);
    printf("Read: %s\\n", buf);
    CloseHandle(hFile);
}

11. Timers

// Set a timer with ID=1, fires every 1000ms (1 second)
SetTimer(hwnd, 1, 1000, NULL);

// Handle in WndProc
case WM_TIMER:
    if (wParam == 1) {
        // Called every second — update UI, check state, etc.
        InvalidateRect(hwnd, NULL, TRUE); // Trigger repaint
    }
    break;

// Stop the timer when no longer needed
KillTimer(hwnd, 1);

12. Registry Read/Write

HKEY hKey;

// --- Write a registry value ---
// Opens or creates a subkey under HKCU
RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Software\\\\MyApp"),
               0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL);

DWORD val = 42;
RegSetValueEx(hKey, TEXT("MyValue"), 0, REG_DWORD,
              (BYTE*)&val, sizeof(val)); // Write DWORD value
RegCloseKey(hKey);

// --- Read a registry value ---
RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\\\MyApp"),
             0, KEY_READ, &hKey);

DWORD data, size = sizeof(data);
RegQueryValueEx(hKey, TEXT("MyValue"), NULL, NULL,
                (BYTE*)&data, &size); // Read into 'data'
RegCloseKey(hKey);
printf("Registry value: %lu\\n", data);

🔴 ADVANCED

13. Threads

// Thread function — must match LPTHREAD_START_ROUTINE signature
DWORD WINAPI MyThread(LPVOID lpParam) {
    int* val = (int*)lpParam;    // Cast the parameter
    printf("Thread got: %d\\n", *val);
    return 0; // Exit code
}

int data = 99;
HANDLE hThread = CreateThread(
    NULL,       // Default security
    0,          // Default stack size
    MyThread,   // Thread function
    &data,      // Parameter passed to thread
    0,          // Run immediately (use CREATE_SUSPENDED to delay)
    NULL        // Don't need thread ID
);

WaitForSingleObject(hThread, INFINITE); // Block until thread finishes
CloseHandle(hThread);

14. Mutex (Thread Synchronization)

// Create a named mutex — prevents multiple instances or race conditions
HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("MyAppMutex"));

if (GetLastError() == ERROR_ALREADY_EXISTS) {
    // Another instance is already running
    MessageBox(NULL, TEXT("Already running!"), TEXT("Error"), MB_OK);
    return 1;
}

// Acquire the mutex (lock) — waits up to 5 seconds
WaitForSingleObject(hMutex, 5000);

// --- Critical section (shared resource access) ---
// ... do thread-safe work here ...

ReleaseMutex(hMutex);  // Release the lock
CloseHandle(hMutex);

15. Critical Sections (Faster than Mutex for same-process)

CRITICAL_SECTION cs;
InitializeCriticalSection(&cs); // Init once at startup

// In each thread, wrap shared data access:
EnterCriticalSection(&cs);   // Lock — only one thread enters at a time
    // ... access shared data safely ...
LeaveCriticalSection(&cs);   // Unlock

DeleteCriticalSection(&cs);  // Cleanup on exit

16. Process Creation

STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
si.cb = sizeof(si); // Must set this field

// Launch notepad.exe as a child process
BOOL ok = CreateProcess(
    NULL,                    // No module name (use command line)
    TEXT("notepad.exe"),     // Command line
    NULL, NULL,              // Process/Thread security attributes
    FALSE,                   // Don't inherit handles
    0,                       // Normal priority
    NULL,                    // Use parent's environment
    NULL,                    // Use parent's working directory
    &si, &pi
);

if (ok) {
    WaitForSingleObject(pi.hProcess, INFINITE); // Wait for it to finish
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
}

17. Memory Mapped Files (Shared Memory Between Processes)

// Process A — create and write
HANDLE hMap = CreateFileMapping(
    INVALID_HANDLE_VALUE,   // Use paging file (not a real file)
    NULL,
    PAGE_READWRITE,
    0, 256,                 // Max size: 256 bytes
    TEXT("MySharedMem")     // Named so other processes can open it
);

LPVOID pBuf = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 256);
CopyMemory(pBuf, "Hello from A!", 14); // Write to shared memory

// Process B — open and read
HANDLE hMap2 = OpenFileMapping(FILE_MAP_READ, FALSE, TEXT("MySharedMem"));
LPVOID pBuf2 = MapViewOfFile(hMap2, FILE_MAP_READ, 0, 0, 256);
printf("Shared: %s\\n", (char*)pBuf2);

// Cleanup
UnmapViewOfFile(pBuf);  CloseHandle(hMap);
UnmapViewOfFile(pBuf2); CloseHandle(hMap2);

18. Hooks (Global Keyboard Hook)

HHOOK hHook;

// Callback for low-level keyboard events
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode == HC_ACTION) {
        KBDLLHOOKSTRUCT* kb = (KBDLLHOOKSTRUCT*)lParam;
        if (wParam == WM_KEYDOWN) {
            printf("Key pressed: %lu\\n", kb->vkCode);
        }
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam); // MUST call this!
}

// Install the hook
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0);

// Run message loop to keep hook alive
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) DispatchMessage(&msg);

// Remove hook when done
UnhookWindowsHookEx(hHook);

19. Custom Drawing with GDI

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

    // Draw a filled rectangle
    HBRUSH hBrush = CreateSolidBrush(RGB(0, 120, 215)); // Blue brush
    RECT rc = {50, 50, 200, 150};
    FillRect(hdc, &rc, hBrush);
    DeleteObject(hBrush); // Always delete GDI objects!

    // Draw a line
    MoveToEx(hdc, 0, 0, NULL);    // Move pen to (0,0)
    LineTo(hdc, 300, 300);        // Draw line to (300,300)

    // Draw text with custom font
    HFONT hFont = CreateFont(24, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE,
        DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
        DEFAULT_QUALITY, DEFAULT_PITCH, TEXT("Arial"));
    SelectObject(hdc, hFont);         // Apply font to DC
    SetTextColor(hdc, RGB(255,255,255));
    SetBkMode(hdc, TRANSPARENT);      // Transparent text background
    TextOut(hdc, 60, 90, TEXT("Win32 GDI"), 9);
    DeleteObject(hFont);

    EndPaint(hwnd, &ps);
    break;
}

20. Window Subclassing

// Save original WndProc of a control (e.g., an EDIT box)
WNDPROC OldEditProc;

LRESULT CALLBACK SubclassProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (msg == WM_KEYDOWN && wParam == VK_RETURN) {
        MessageBox(hwnd, TEXT("Enter pressed in edit!"), TEXT(""), MB_OK);
        return 0; // Eat the message
    }
    // Pass everything else to the original handler
    return CallWindowProc(OldEditProc, hwnd, msg, wParam, lParam);
}

// Subclass the edit control
HWND hEdit = CreateWindow(TEXT("EDIT"), ..., hwnd, (HMENU)2, hInstance, NULL);
OldEditProc = (WNDPROC)SetWindowLongPtr(hEdit, GWLP_WNDPROC, (LONG_PTR)SubclassProc);

21. COM Basics (Component Object Model)

#include <windows.h>
#include <shobjidl.h>  // IFileOpenDialog

// COM must be initialized before use
CoInitialize(NULL);

IFileOpenDialog* pDialog = NULL;

// Create a COM object (File Open Dialog)
CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER,
                 &IID_IFileOpenDialog, (void**)&pDialog);

pDialog->lpVtbl->Show(pDialog, NULL); // Show the dialog

IShellItem* pItem = NULL;
pDialog->lpVtbl->GetResult(pDialog, &pItem); // Get selected file

PWSTR filePath;
pItem->lpVtbl->GetDisplayName(pItem, SIGDN_FILESYSPATH, &filePath);
// filePath now holds the selected file path (wide string)

CoTaskMemFree(filePath);       // Free COM-allocated string
pItem->lpVtbl->Release(pItem); // Release COM objects when done
pDialog->lpVtbl->Release(pDialog);

CoUninitialize(); // Cleanup COM

22. Useful Macros & Helpers Quick Reference

// ---- Bit manipulation helpers ----
LOWORD(0xABCD1234)   // → 0x1234 (lower 16 bits) — used for coords/IDs
HIWORD(0xABCD1234)   // → 0xABCD (upper 16 bits)
MAKELONG(lo, hi)     // Combine two WORDs into a DWORD

// ---- Window helpers ----
GetClientRect(hwnd, &rc);           // Get window's inner drawable area
SetWindowText(hwnd, TEXT("New Title")); // Change window title
GetWindowText(hwnd, buf, 256);      // Read window title
EnableWindow(hwnd, FALSE);          // Disable/grey out a control
ShowWindow(hwnd, SW_HIDE);          // Hide a window
InvalidateRect(hwnd, NULL, TRUE);   // Force window to repaint

// ---- Screen/cursor ----
GetCursorPos(&pt);                  // Get mouse position on screen
ScreenToClient(hwnd, &pt);         // Convert screen → window coordinates
GetSystemMetrics(SM_CXSCREEN);      // Screen width in pixels
GetSystemMetrics(SM_CYSCREEN);      // Screen height in pixels

// ---- Module/path ----
GetModuleFileName(NULL, buf, 256);  // Path of current .exe
GetCurrentDirectory(256, buf);      // Current working directory
SetCurrentDirectory(TEXT("C:\\\\"));  // Change working directory

// ---- Timing ----
DWORD t = GetTickCount();           // Milliseconds since system boot (32-bit wraps)
ULONGLONG t2 = GetTickCount64();    // 64-bit version — no wrap issues
Sleep(1000);                        // Pause thread for 1000ms

📌 Quick Flags Reference

FlagMeaning
MB_OKMessage box with OK button
MB_YESNOYes/No buttons
MB_ICONERRORError icon
MB_ICONWARNINGWarning icon
WS_OVERLAPPEDWINDOWStandard window with title/borders
WS_CHILDChild control (inside another window)
WS_VISIBLEMake visible immediately
`CS_HREDRAW \CS_VREDRAW`
VK_ESCAPEEscape virtual key
VK_RETURNEnter virtual key
GENERIC_READOpen file for reading
GENERIC_WRITEOpen file for writing
CREATE_ALWAYSCreate/overwrite file
OPEN_EXISTINGOpen only if exists

Built for Win32 C/C++ development. Compile with -luser32 -lgdi32 -lkernel32 or use Visual Studio / MinGW.

On this page