ScrollWindow不会重绘某些区域

时间:2012-05-12 21:31:30

标签: winapi

我在Charles Petzold的书“Programming Windows”中作了一个例子。该示例显示键盘事件发生时的键盘消息。它会自动滚动以显示显示。这是代码的一部分(有一些小修改)。问题是:通常,当收到键盘消息时,它应该在底部显示0。当收到另一个键盘消息时,它向下滚动一行,在底部显示0,在底部上方,它应显示1。 但我所拥有的是它始终显示0.只有当我调整窗口大小时,我得到正确的结果,如:...... 4,3,2,1,0。我认为问题是当某些东西没有被重新绘制时它叫ScrollWindow,但我不知道究竟是什么问题,因为我跟着这本书。

    case WM_SIZE:

        if (message == WM_SIZE)
        {   cxClient = LOWORD (lParam);
            cyClient = HIWORD (lParam);
        }

        // Calculate scrolling rectangle

        rectScroll.left   = 0;
        rectScroll.right  = cxClient;
        rectScroll.top    = cyChar;
        rectScroll.bottom = cyChar * ( cyClient / cyChar);

        InvalidateRect(hwnd, NULL, TRUE);

        return 0;

    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_CHAR:
    case WM_DEADCHAR:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_SYSCHAR:
    case WM_SYSDEADCHAR:

        for ( i = cLinesMax - 1; i > 0 ; i-- )
        {
            pmsg[i] = pmsg[i - 1];
        }

        // Store new message

        pmsg[0].hwnd    = hwnd;
        pmsg[0].message = message;
        pmsg[0].wParam  = wParam;
        pmsg[0].lParam  = lParam;

        cLines = min(cLines + 1, cLinesMax);

        // Scroll up the display

        ScrollWindow(hwnd, 0, -cyChar, &rectScroll, &rectScroll);

        break; // call DefWindowProc so System messages work

    case WM_PAINT:

        hdc = BeginPaint(hwnd, &ps);

        for (i = 0; i < min(cLines, cyClient / cyChar - 1); i++)
        {
            TextOut(hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,
                    wsprintf(szBuffer, TEXT("%5d"), i));

        }

1 个答案:

答案 0 :(得分:3)

ScrollWindow()的重点是移动窗口的现有内容,而不需要重绘所有内容。基本假设是移动的内容不会因滚动操作而改变,只需要绘制“未覆盖”区域。

在您的示例中,您希望更改内容(通过重新编号行),而不仅仅是移动。这意味着需要重新绘制 - 您的密钥消息处理中的ScrollWindow()不会导致,但InvalidateRect()处理程序中的WM_SIZE会这样做。