【问题标题】:Win32 WndProc as class memberWin32 WndProc 作为类成员
【发布时间】:2013-01-20 11:43:53
【问题描述】:

有没有办法将 WndProc 包装为私有成员?

如果我有这个:

class Window
{
public:
    Window();
    virtual ~Window();
    void create();

private:
    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
};

在我的create() 这个:

WNDCLASSEX wc;
wc.lpfnWndProc = (WNDPROC) &Window::WndProc;

我收到此警告:

warning: converting from 'LRESULT (Window::*)(HWND, UINT, WPARAM, LPARAM) {aka long int (Window::*)(HWND__*, unsigned int, unsigned int, long int)}' to 'WNDPROC {aka long int (__attribute__((__stdcall__)) *)(HWND__*, unsigned int, unsigned int, long int)}' [-Wpmf-conversions]

而我的窗口HWNDNULLGetLastError() 也返回 0。

如何解决这个问题?

【问题讨论】:

    标签: c++ winapi mingw


    【解决方案1】:

    将其设为静态:

    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    

    【讨论】:

    • 嗯,这很有趣..它对我有用。但是我从 wndProc 调用了许多函数,它们都不是静态的,那么如何实现呢?我不想让它们成为静态的..
    【解决方案2】:

    你应该给它添加static修饰符。

    原因在于,当它是成员函数(我相信它是 Visual C++ 中的 __thiscall)时,它实际上只是一个将 this 作为第一个参数的 C 函数。这看起来像这样:

    LRESULT CALLBACK WndProc(Window& this, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    

    如果将其设为静态,编译器会去掉第一个 Window& this 参数,使其与 lpfnWndProc 兼容。

    【讨论】:

      【解决方案3】:

      是的,可以将 WndProc 包含为类成员。此外,您可以从中修改其他类成员。诀窍是使用两个 WndProc 函数,其中一个是静态的。

      【讨论】:

      • 除此之外,技巧的第二部分是在窗口的 win32 类上设置指向 C++ 类实例的指针,方法是将 cbWndExtra 设置为指针的大小,并使用 @ 987654322@ 设置指针。然后在您的静态方法中,使用GetWindowLongPtr 获取指向 C++ 类的指针,并使用它来调用您的特定于实例的方法。
      猜你喜欢
      • 1970-01-01
      • 2018-12-24
      • 2012-09-16
      • 2013-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多