C2440用于重载函数MsgProc

C2440 for overloaded function MsgProc

本文关键字:MsgProc 函数 重载 用于 C2440      更新时间:2023-10-16

这是这个问题的延续。

我有以下任务:

WNDCLASSEX wndClass =
{
    sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0, 0,
    GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
    "D3D Tutorial", NULL
};
wc = wndClass;

这给了我以下错误:

1> e:\rat_engine\rat_egine\rat_engine \rat_renderdx9.cpp(19):错误C2440:"正在初始化":无法从"重载函数"转换为'WNDPROC'

1> 作用域中没有此名称的函数匹配目标类型

将MsgProc下划线作为原因,它应该引用以下函数:

LRESULT WINAPI RAT_RendererDX9::MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    switch( msg )
    {
        case WM_DESTROY:
            CleanUp();
            PostQuitMessage( 0 );
            return 0;
        case WM_PAINT:
            Render();
            ValidateRect( hWnd, NULL );
            return 0;
    }
    return DefWindowProc( hWnd, msg, wParam, lParam );
}

在教程中,它是这样工作的,我几乎完全复制了它。那么这个错误是从哪里来的,我该如何修复它呢?

编辑:

MsgProc的声明为:

private:
    LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );

MsgProc的声明来看,它似乎是一个常规成员函数,这意味着它使用了一个"隐藏"的this指针。这使得它与WNDPROC不兼容,这就是编译器抱怨的原因。

尝试将其标记为static。当然,这意味着您无法轻松访问类的非静态成员——您需要将实例的this指针的副本存储在某个位置。

您可能还需要CALLBACK而不是WINAPI,但我现在无法轻松访问编译器来验证这一点。

对我来说,将类的实例/对象绑定到HWND似乎是最优雅的。要设置和检索指向实例的指针,可以使用SetWindowLongPtr/GetWindowLongPtr

因此,在创建窗口后,您可以调用

SetWindowLongPtr(hWnd, GWLP_USERDATA, static_cast<LONG_PTR>(this));

在你的WindowProcedure中,你打电话给

YourClass* instance = static_cast<YourClass*> (GetWindowLongPtr(hWnd, GWLP_USERDATA));

WindowProcedure中要小心:当您创建窗口时,它已经被调用了,但很明显,您只能在之后调用SetWindowLongPtr。因此,当您的WindowProcedure首先被调用时,GetWindowLongPtr将失败。请确保该函数在这些情况下也能正常工作。