0

グローバルWindowProc関数からGUIクラスにメッセージを送信しようとしています。メッセージは次のように定義されています。

#define WM_ENV_RESIZED (WM_APP + 0)

私のWindowProc関数は次のようになります

LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int res;
    switch (message)
    {
        case WM_SIZE:
            std::cout << "window resized" << std::endl;

            res = PostMessage(hWnd, WM_ENV_RESIZED, 0, 0);
            if ( res == 0 )    //<-- res is never 0
            {
                std::cout << "PostMessage failure!" << std::endl;
                std::cout << "Error code: " << GetLastError() << std::endl;
            }
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
    }

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

メッセージは、次のようにGUIクラスで受信されます。

MSG msg;
while (running)
{
    while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
        processWindowsMessage(&msg);

    //DirectX render calls
}

今私の問題は、メッセージがPeekMessage()によって受信されないことです。ウィンドウが作成されたときに一度だけ受信されます。その後、それは決して受け取られません。

PostMessage()の直後にGetLastError()を呼び出すと、MSDNによるとERROR_INVALID_HANDLEを表すエラーコード6が常に返されます。ただし、PostMessage()が0を返すことはないため、これは意味がありません。これは、投稿中に問題が発生したことを意味します。メッセージキューをバイパスし、SendMessage()を使用してメッセージをウィンドウに直接送信しようとしましたが、常に0が返されます(同じエラーコード6 ..)。

何が間違っているのか本当にわかりません。PeekMessage()を使用しているときに、投稿されたメッセージが常に受信されるようにするにはどうすればよいですか?

編集: レミーが提案したように、メッセージループを更新しました。以下はprocessWindowsMessage()のコードです

void Environment::processWindowsMessage( MSG *msg )
{
    switch ( msg->message )
    {
        case WM_ENV_RESIZED:
            std::cout << "WM_ENV_RESIZED caught" << std::endl;
            break;
        case WM_QUIT:
            running = false;
            break;
        default:
            TranslateMessage(msg);
            DispatchMessage(msg);
            break;
    }
}
4

1 に答える 1

1

メッセージはサイズ変更されているのと同じウィンドウに投稿されているため、そのウィンドウをDispatchMessage()対象とする他のメッセージと同様に、メッセージをウィンドウのプロシージャに送信します。だからどちらか:

1):内のメッセージを処理しwindowProcedure()ます

LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_SIZE:
            std::cout << "window resized" << std::endl;

            if (!PostMessage(hWnd, WM_ENV_RESIZED, 0, 0))
            {
                std::cout << "PostMessage failure!" << std::endl;
                std::cout << "Error code: " << GetLastError() << std::endl;
            }
            break;

        case WM_ENV_RESIZED:
            std::cout << "env resized" << std::endl;
            //...
            return 0;
    }

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

MSG msg;
while (running)
{
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    //DirectX render calls
}

2)ウィンドウプロシージャでカスタムメッセージを処理したくない場合は、メッセージループを変更して、TranslateMessage()およびDispatchMessage()呼び出しをに移動processWindowsMessage()し、非カスタムメッセージに対してのみ呼び出します。カスタムメッセージを変換/ディスパッチしないでください。

LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_SIZE:
            std::cout << "window resized" << std::endl;

            if (!PostMessage(hWnd, WM_ENV_RESIZED, 0, 0))
            {
                std::cout << "PostMessage failure!" << std::endl;
                std::cout << "Error code: " << GetLastError() << std::endl;
            }
            break;
    }

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

MSG msg;
while (running)
{
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        processWindowsMessage(&msg);

    //DirectX render calls
}

void processWindowsMessage(MSG *msg)
{
    switch (msg->message)
    {
        case WM_ENV_RESIZED:
            std::cout << "env resized" << std::endl;
            //...
            break;

        default:
            TranslateMessage(msg);
            DispatchMessage(msg);
            break;
    }
}
于 2013-02-08T03:59:16.677 に答える