0

我遵循了 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));

        }
4

1 回答 1

3

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

在您的示例中,您想要更改内容(通过重新编号行),而不仅仅是移动它。这意味着它需要重绘——ScrollWindow()在您的关键消息处理中不会导致,但InvalidateRect()在您的WM_SIZE处理程序中会导致。

于 2012-05-12T21:57:45.220 回答