这看起来应该非常简单。我有我的课:
class Simple
{
public:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
}
};
和我的 WinMain
:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR commandLine, int cmdShow)
{
Simple *simple = new Simple();
...
wndClass.lpfnWndProc = simple->WndProc;
...
}
当我尝试时,我得到:
error C2440: '=' :cannot convert from 'LRESULT (__stdcall Simple::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'
我不能在类里面使用 WndProc
有什么原因吗?看来这真的很有用。
最佳答案
C++ 以不同方式对待成员函数和自由函数 - 成员函数需要访问 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 = 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!
}
};
希望这对您有所帮助!
关于c++ - 为什么我的 WndProc 不能在类里面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17221815/