0

だから私は次のことを理解しようとしてきました:

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC hDC;                // Display context handle
    PAINTSTRUCT PaintSt;    // Structure defining area to be drawn
    RECT aRect;             // A working rectangle
    HPEN hPen;              // A working pen
    HBRUSH hBrush;          // A working brush
    switch(message)
    {
        case WM_TIMER:
            switch(wParam)
            {
            case IDT_TIMER1: 
                    redraw = true;
                InvalidateRect(hWnd, NULL, TRUE);
            case IDT_TIMER2:
                if(keys[UP])
            {
                rect2.bottom -= 5;
                rect2.top -= 5;
            }
            if(keys[DOWN])
            {
                rect2.bottom += 5;
                rect2.top += 5;
            }
            if(keys[RIGHT])
            {
                rect2.left += 5;
                rect2.right += 5;
            }
            if(keys[LEFT])
            {
                rect2.left -= 5;
                rect2.right -= 5;
            }
        }
        return 0;
    case WM_PAINT:
            //if(redraw)
            {
                redraw = false;
                render_frame();
            }
        return 0;

    case WM_KEYDOWN:

            switch(wParam)
            {
            case VK_UP:
                keys[UP] = true;
                break;
            case VK_DOWN:
                keys[DOWN] = true;
                break;
            case VK_LEFT:
                keys[LEFT] = true;
                break;
            case VK_RIGHT:
                keys[RIGHT] = true;
                break;
            default:
                break;
            }

        return 0;
    case WM_KEYUP:
        switch(wParam)
        {
        case VK_UP:
            keys[UP] = false;
            break;
        case VK_DOWN:
            keys[DOWN] = false;
            break;
        case VK_LEFT:
            keys[LEFT] = false;
            break;
        case VK_RIGHT:
            keys[RIGHT] = false;
            break;
        default:
                break;
        }
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

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

問題は次のとおりです。WM_PAINT: の場合、 if ステートメントのコメントを外すと、何らかの理由で時間の経過が止まります。理由がわかりませんし、これを何かと関連付ける方法もわかりません。したがって、コメントを外すと、レンダリングされず、他のタイマーからの情報も受信されません (2 つのタイマーがあります)。助けてください。ばかげていても笑わないでください。

4

2 に答える 2

3

WM_TIMER メッセージは「優先度の低い」メッセージであり、他に何もする必要がない場合にのみ生成されます。WM_PAINT ハンドラーの問題は、ウィンドウを作成した直後に初めて生成されたときに描画されないことです。EndPaint() が呼び出されないため、「window is dirty」ステータス ビットがオンのままになります。これにより、すぐに別の WM_PAINT メッセージが生成されます。再描画が正しくないため、まだ描画されません。など、アプリは WM_PAINT メッセージで 100% のコアを燃やしており、WM_TIMER メッセージを生成できるほど十分にアイドル状態になりません。

問題を解決するには、再描画テストを削除するだけです。Windows が要求するときは常に描画します。または、メッセージを DefWindowProc() に渡します。

于 2012-07-09T22:30:24.867 に答える
2

WM_PAINT何も描画せずに(falseのままであると仮定しredrawて)、呼び出しさえせずに処理することDefWindowProcは非常に非正統的です。あなたのアプリはあなたが気付かないうちに生きているかもしれません。

ドキュメントから:

アプリケーションは、WM_PAINTメッセージに応答してBeginPaintとEndPaintを呼び出すか、メッセージをDefWindowProc関数に渡してウィンドウを検証する必要があります。DefWindowProcは更新領域を検証します。ウィンドウの背景を消去する必要がある場合は、WM_ERASEBKGNDメッセージを送信できます。

于 2012-07-09T22:17:01.633 に答える