如何使用WndProc作为类函数

Ami*_*mit 3 c c++ winapi class

我正在尝试创建一个包含WndProc的类,但是我收到一个错误:

Error 2 error C2440: '=' : cannot convert from 'LRESULT (__stdcall Client::* )(HWND,UINT,WPARAM,LPARAM)' to 'WNDPROC'

我在网上搜索它,看到你需要让WndProc静态,但是,它编译并且一切都很好,但如果我想改变一些东西,它不会让我:

Error 3 error C2352: 'Client::CreateMen' : illegal call of non-static member function

(CreateMen是创建菜单的类中的一个函数,使用HMENU等).

这是我的职称:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
Run Code Online (Sandbox Code Playgroud)

我能做什么?我真的很困惑......

谢谢!

Rem*_*eau 16

非静态类方法具有隐藏this参数.这就是阻止该方法用作WndProc(或任何其他API回调)的原因.您必须声明类方法static以删除该this参数.但正如您已经注意到的那样,您无法从静态方法访问非静态成员.您需要一个指向该对象的指针才能访问它们.

在WndProc回调的特定情况下,您可以将对象指针存储在HWND本身中(使用SetWindowLong/Ptr(GWL_USERDATA)或者SetProp()),然后静态方法可以从hWnd参数中检索该对象指针(使用GetWindowLong/Ptr(GWL_USERDATA)GetProp())并使用该对象访问非静态成员根据需要指针.例如:

private:
    HWND m_Wnd;
    static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
Run Code Online (Sandbox Code Playgroud)

LRESULT CALLBACK Client::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    Client *pThis;

    if (msg == WM_NCCREATE)
    {
        pThis = static_cast<Client*>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams);

        SetLastError(0);
        if (!SetWindowLongPtr(hwnd, GWL_USERDATA, reinterpret_cast<LONG_PTR>(pThis)))
        {
            if (GetLastError() != 0)
                return FALSE;
        }
    }
    else
    {
        pThis = reinterpret_cast<Client*>(GetWindowLongPtr(hwnd, GWL_USERDATA));
    }

    if (pThis)
    {
        // use pThis->member as needed...
    }

    return DefWindowProc(hwnd, msg, wParam, lParam);
}
Run Code Online (Sandbox Code Playgroud)

m_Wnd = CreateWindowEx(..., this);
Run Code Online (Sandbox Code Playgroud)