Pergunta

Currently I'm learning Win32 and C++ and I finished my first application. Now I want to translate the code from functional style to OOP. Here is a shortened version of my code:

#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
}

How to bind the derived class's WndProc to the parent class's wnd.lpfnWndProc in BaseWindow::Register?

Foi útil?

Solução

You cannot use a non-static class method as a window procedure callback. The parameter list is not compatible due to the hidden this pointer. What you have to do instead is:

  1. In BaseWindow, define a static method as the actual message callback registered with RegisterClassEx(), and then define a separate virtual method for processing messages. Have the BaseWindow implementation of the virtual method call DefWindowProc(), and descendants that override the virtual method need to call the base method for unhandled messages.

  2. Pass the object's this pointer as the lpCreateParam of CreateWindow/Ex().

  3. In the WM_NCCREATE message handler, retrieve the lpCreateParam value from the message and assign it to the HWND using either SetWindowLongPtr(GWL_USERDATA) or SetProp(), then type-cast the value to a BaseWindow* pointer and use it to call the virtual method.

  4. For subsequent messages, use GetWindowLongPtr(GWL_USERDATA) or GetProp() to retrieve the BaseWindow* pointer from the HWND and use it to call the virtual method.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top