C++ Win32 API wrapper: Passing object pointer to static callback function

I’m working on a C++ wrapper for the Win32 API and I’m stuck on a problem. How can I pass the this pointer to a static callback function?

Here’s what I’m trying to do:

class WindowWrapper {
private:
    static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        // How do I call a member function here?
    }

public:
    LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        // Actual window procedure logic
    }

    void Create() {
        WNDCLASS wc = {};
        wc.lpfnWndProc = StaticWndProc;
        // Other initialization...
    }
};

I want StaticWndProc to call the non-static WndProc method. But I can’t figure out how to get the this pointer inside the static function. Any ideas on how to solve this? I’m new to Win32 programming and C++ object-oriented design, so I’d appreciate any help or suggestions for a better approach.

Another approach you might consider is using a template class with a static member function. This method allows you to avoid the SetWindowLongPtr/GetWindowLongPtr dance altogether.

Here’s a basic implementation:

template <class T>
class WindowBase {
protected:
    static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        T* pThis;
        if (msg == WM_NCCREATE) {
            CREATESTRUCT* pCreate = reinterpret_cast<CREATESTRUCT*>(lParam);
            pThis = static_cast<T*>(pCreate->lpCreateParams);
            SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(pThis));
        } else {
            pThis = reinterpret_cast<T*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
        }
        
        if (pThis) {
            return pThis->WndProc(hwnd, msg, wParam, lParam);
        }
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
};

class MyWindow : public WindowBase<MyWindow> {
public:
    LRESULT WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
        // Your window procedure logic here
    }
};

This solution is type-safe and doesn’t require manual pointer management in your derived classes.

I’ve faced this exact issue before when wrapping Win32 API. The solution I found was to use SetWindowLongPtr to store the ‘this’ pointer when creating the window, then retrieve it in the static callback.

Here’s how I did it:

In the Create method:

HWND hwnd = CreateWindow(...);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));

Then in StaticWndProc:

WindowWrapper* pThis = reinterpret_cast<WindowWrapper*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (pThis) {
    return pThis->WndProc(hwnd, msg, wParam, lParam);
}

This approach worked well for me, allowing the static callback to route messages to the appropriate instance method. Just remember to handle the WM_NCCREATE message separately, as the GWLP_USERDATA won’t be set yet when it’s first called.

hey, i’ve dealt with this before. one trick is to use SetWindowLongPtr to store the ‘this’ pointer when you create the window. then in StaticWndProc, you can grab it back with GetWindowLongPtr. it’s a bit hacky but it works pretty well. just remember to handle WM_NCCREATE separately cuz the pointer won’t be set yet when that first comes in.