【问题标题】:Pointer to function of derived class withing parent class [closed]指向父类中派生类函数的指针[关闭]
【发布时间】:2014-03-06 06:33:18
【问题描述】:

目前我正在学习 Win32 和 C++,并完成了我的第一个应用程序。现在我想将代码从功能样式转换为 OOP。这是我的代码的缩短版本:

#include <Windows.h>

class BaseWindow {
    public:
    BaseWindow ();
    virtual LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) abstract;
    bool Register ();
};

BaseWindow::BaseWindow () {}

bool BaseWindow::Register () {
    WNDCLASSEXW wnd = {0};
    wnd.lpfnWndProc = &BaseWindow::WndProc;    // Error | How to point to the derived class's WndProc
    // Some other properties
    return RegisterClassExW(&wnd) != NULL;
}



class MainWindow : BaseWindow {
    using BaseWindow::Register;

    public:
    MainWindow();
    bool Register ();
    LRESULT CALLBACK WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
};

MainWindow::MainWindow () : BaseWindow () {}

LRESULT CALLBACK MainWindow::WndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    // Handling messages
}

如何将派生类的WndProc绑定到BaseWindow::Register中父类的wnd.lpfnWndProc

【问题讨论】:

  • 有问题吗?并且您注册的WndProc 需要是static 或与班级友好的独立外部函数。您不能将简单的成员函数用作注册的 wndproc 回调。
  • 谢谢。我不知道。有没有办法将lpfnWndProc 绑定到类的成员?
  • 有,但不一定是微不足道的(至少对初学者来说不是)。一种方法can be seen here。通常,它涉及提供您的对象指针作为 windows api CreateWindow 创建参数的一部分,然后将该指针存储在窗口实例的窗口额外字节中以供将来在调度消息时使用。阅读该链接。它不是(恕我直言)理想,但它是一种方式。

标签: c++ winapi pointers derived-class base-class


【解决方案1】:

您不能将非静态类方法用作窗口过程回调。由于隐藏的this 指针,参数列表不兼容。你需要做的是:

  1. BaseWindow中,定义一个静态方法作为在RegisterClassEx()注册的实际消息回调,然后定义一个单独的虚拟方法来处理消息。让虚拟方法的BaseWindow 实现调用DefWindowProc(),覆盖虚拟方法的后代需要调用未处理消息的基方法。

  2. 将对象的this 指针作为CreateWindow/Ex()lpCreateParam 传递。

  3. WM_NCCREATE 消息处理程序中,从消息中检索lpCreateParam 值并使用SetWindowLongPtr(GWL_USERDATA)SetProp() 将其分配给HWND,然后将值类型转换为BaseWindow*指针并用它来调用虚方法。

  4. 对于后续消息,使用GetWindowLongPtr(GWL_USERDATA)GetProp()从HWND中检索BaseWindow*指针并使用它来调用虚方法。

【讨论】:

    猜你喜欢
    • 2017-12-27
    • 2021-07-07
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    相关资源
    最近更新 更多