我在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));
}
答案 0 :(得分:3)
ScrollWindow()
的重点是移动窗口的现有内容,而不需要重绘所有内容。基本假设是移动的内容不会因滚动操作而改变,只需要绘制“未覆盖”区域。
在您的示例中,您希望更改内容(通过重新编号行),而不仅仅是移动。这意味着需要重新绘制 - 您的密钥消息处理中的ScrollWindow()
不会导致,但InvalidateRect()
处理程序中的WM_SIZE
会这样做。