Ответ 1
С++ рассматривает функции-члены и свободные функции, поскольку функции-члены-члены должны иметь доступ к указателю this
, и обычно это передается как скрытый первый параметр. Следовательно, функция-член n-аргумента будет больше всего похожа на функцию (n + 1) -аргумента, что означает, что код, пытающийся вызвать ваш WndProc
, будет содержать неправильное количество аргументов.
Вы можете, однако, объявить WndProc
как функцию члена static
, которая устраняет указатель this
. Этот код должен работать:
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;
...
}
Конечно, это означает, что вы не можете напрямую обращаться к полям класса. Вы можете обойти это, введя указатель на класс в дополнительные байты, зарезервированные для каждого экземпляра окна, возможно, используя SetWindowLongPtr
. Как только вы это сделаете, вы можете восстановить указатель объекта получателя, написав что-то вроде этого:
class Simple
{
public:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Simple* me = static_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!
}
};
Надеюсь, это поможет!