Why can't my WndProc be in a class?
C++ treats member functions and free functions as different - member functions need to have access to a this
pointer, and typically that's passed in as a hidden first parameter. Consequently, an n-argument member function would be most similar to an (n+1)-argument free function, which means that code trying to call your WndProc
would pass in the wrong number of arguments.
You can, however, declare WndProc
as a static
member function, which eliminates the this
pointer. This code should work:
class Simple
{
public:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR commandLine, int cmdShow)
{
Simple *simple = new Simple();
...
wndClass.lpfnWndProc = simple->WndProc;
...
}
Of course, this means you can't directly access the fields of the class. You could get around this by embedding a pointer to the class into the extra bytes reserved for each window instance, perhaps by using SetWindowLongPtr
. Once you've done that, you can recover the receiver object pointer by writing something like this:
class Simple
{
public:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Simple* me = reinterpret_cast<Simple*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (me) return me->realWndProc(hwnd, msg, wParam, lParam);
return DefWindowProc(hwnd, msg, wParam, lParam);
}
private:
LRESULT CALLBACK realWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Yay! I'm a member function!
}
};
Hope this helps!