c++ - 为什么我的 WndProc 不能在类里面?

标签 c++ winapi

这看起来应该非常简单。我有我的课:

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/

相关文章:

c++ - std::less 是否必须与指针类型的相等运算符一致?

windows - 启动 WinAPI 和 Qt?

C: WinAPI CreateDIBitmap() 来自 byte[] 问题

c++ - PVS-Studio 提示 float 比较

c++ - 处理孙子控件的 WM_NOTIFY

c++ - 如何将应用程序作为新创建的资源管理器进程的子进程启动?

c - 在 C 中读取文件和 CryptUnprotectData

c++ - 为什么不能从派生类对象访问父类的赋值运算符

c++ - 终止 unicode 空字符

c++ - curl 请求的用户输入