1

我目前正在尝试开发一个基于 DirectX 和 Win32 API 的小型渲染引擎。我目前试图解决的问题是如何正确组织我的代码以处理影响 DirectX 代码的 Windows 消息(例如,WM_SIZE 消息,这意味着调整 DirectX 缓冲区的大小)。

它需要在创建窗口时传递给窗口的 WndProc 函数中完成,但我不知道如何“传输”我感兴趣的消息。到目前为止,我只找到了这种方式:

//main.cpp
Renderer* renderer;

//some code 

//The window procedure
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    PAINTSTRUCT ps;
    HDC hdc;

    //We forward the message to the Renderer, which handles it or not
    if(renderer->HandleMessage(hWnd,message,wParam,lParam){
        return 0;
    }

    //If the renderer does not handle the message, we do as usual
    switch( message )
    {
        case WM_PAINT:
            hdc = BeginPaint( hWnd, &ps );
            EndPaint( hWnd, &ps );
            break;

        case WM_DESTROY:
            PostQuitMessage( 0 );
            break;

        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }

    return 0;
}

我对这种方法的问题是它依赖于一个全局变量(渲染器),我对此感到不舒服,因为我听说很多使用全局变量不是好的做法(而且我觉得我没有经验足以决定我是否应该使用它)

我想知道是否有更好的方法来“转发”窗口消息而不需要全局变量。

4

1 回答 1

3

首先,WM_PAINT 用于 GDI 绘画,而不是 Direct3D 渲染。通常,D3D 应用程序会尽可能渲染帧。

其次,使用SetWindowLongPtr将指向渲染器的指针设置为与 HWND 关联的内部 Windows 变量,您可以使用GetWindowLongPtr.

第三,你真的应该有一个 Window 类来包装它,然后选择告诉渲染器它,而不是直接交互。

编辑:这是正常的超简单结构:

class Window {
    HWND hwnd;
    static ... WindowProc(...) {
        if (auto p = GetWindowLongPtr(hwnd, GWLP_USERDATA))
            return reinterpret_cast<Window*>(p)->ProcessMessage(...);
        else return DefWindowProc(...);
    }
    ... ProcessMessage(...) {
        /* whatever you want */
        if (msg == WM_RESIZE)
            OnResize(...);
    }
public:
    Window() {
        hwnd = CreateWindowEx(...);
        SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
    }
    std::function<void(unsigned, unsigned)> OnResize;
};

在这种情况下,ProcessMessage() 是一个成员,Window 只提供一个回调,允许任何外部代码挂钩到这个特定事件。

于 2013-03-06T19:00:33.007 回答