December 12, 2025 nullprogram.com/blog/2025/12/12/ Back in 2017 I wrote about a technique for creating closures in C using JIT-compiled wrapper. It’s neat, though rarely necessary in real programs, so I don’t think about it often. I applied it to qsort, which sadly accepts no context pointer. More practical would be working around insufficient custom allocator interfaces, to create allocation functions at run-time bound to a particular allocation region. I’ve learned a lot since I last wrote about this subject, and a recent article had me thinking about it again, and how I could do better than before. In this article I will enhance Win32 window procedure callbacks with a fifth argument, allowing us to more directly pass extra context. I’m using w64devkit on x64, but the everything here should work out-of-the-box with any x64 toolchain that speaks GNU assembly. A window procedure has this prototype: LRESULT Wndproc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam, ); To create a window we must first register a class with RegisterClass, which accepts a set of properties describing a window class, including a pointer to one of these functions. MyState *state = ...; RegisterClassA(&(WNDCLASSA){ // ... .lpfnWndProc = my_wndproc, .lpszClassName = "my_class", // ... }); HWND hwnd = CreateWindowExA("my_class", ..., state); The thread drives a message pump with events from the operating system, dispatching them to this procedure, which then manipulates the program state in response: for (MSG msg; GetMessageW(&msg, 0, 0, 0);) { TranslateMessage(&msg); DispatchMessageW(&msg); // calls the window procedure } All four WNDPROC parameters are determined by Win32. There is no context pointer argument. So how does this procedure access the program state? We generally have two options: Global variables. Yucky but easy. Frequently seen in tutorials. A GWLP_USERDATA pointer attached to the window. The second option takes some setup. Win32 passes the last CreateWindowEx argument to th...
First seen: 2025-12-13 23:53
Last seen: 2025-12-14 03:53