The usual thing is something in this order:
#include <windows.h> class BaseWindow { static LRESULT CALLBACK internal_WndProc(HWND hWnd, int msg, WORD wParam, LONG lParam) { BaseWindow *c = (BaseWindow *)GetWindowLong(hWnd,GWLP_USERDATA); if (c == NULL) return DefWindowProc(hWnd, msg, wParam, lParam); return c->WindowProc(hWnd, msg, wParam, lParam); } public: virtual int WindowProc(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam) = 0; BaseWindow(HINSTANCE instance) { WNDCLASS window_class = {0}; HWND window; HMENU my_menu; window_class.lpfnWndProc = (WNDPROC)internal_WndProc; /* fill in window_class here */ RegisterClass(&window_class); window = CreateWindow( "My Application", "Stupidity", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, my_menu, instance, NULL); // save the address of the class as the Window USERDATA. SetWindowLong(window, GWLP_USERDATA, (long)this); } };
In doing so, you get a class from BaseWindow. In a derived class, you provide a "WindowProc" that overrides (pure virtual) in BaseWindow. The trick here is quite simple: since you cannot pass the parameter directly, you store the class address in the GWLP_USERDATA window, then in the proc window (try) to extract it and use the proc window to call the virtual class of the derived class.
Note that this is a sketch, not a completed work (so to speak). Although it should compile as is, the result will not actually work unless you fill in quite a few pieces that are not here (for example, other fields of the WNDCLASS structure are only one of the most obvious).