1

私は現在、DirectX と Win32 API に基づく小さなレンダリング エンジンを開発しようとしています。私が現在解決しようとしている問題は、コードを正しく整理して、DirectX コードに影響を与える Windows メッセージ (たとえば、DirectX バッファーのサイズ変更を意味する WM_SIZE メッセージ) を処理する方法です。

ウィンドウの作成時にウィンドウに渡される 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 は Direct3D レンダリングではなく、GDI ペイント用です。通常、D3D アプリは可能な限りフレームをレンダリングします。

次に、 を使用SetWindowLongPtrして、レンダラーへのポインターを HWND に関連付けられた内部 Windows 変数に設定します。これは で取得できますGetWindowLongPtr

3 番目に、これをラップする 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() はメンバーであり、ウィンドウは外部コードがこの特定のイベントにフックできるようにするコールバックを提供するだけです。

于 2013-03-06T19:00:33.007 に答える