2012-05-12 2 views
0

Я следовал примеру в книге Чарльза Петцольда «Программирование Windows». Этот пример показывает сообщение клавиатуры, когда происходит событие клавиатуры. Он автоматически прокручивается, чтобы отобразить дисплей. Вот часть кода (с небольшой модификацией). Проблема в том, что: обычно, когда принимается сообщение клавиатуры, оно должно отображать 0 внизу. Когда получено другое сообщение с клавиатуры, оно прокручивается по строке, отображает 0 в нижней части и над нижней, оно должно отображать 1. Но у меня есть то, что оно отображается всегда 0. Только когда я изменяю размер окна, я получите правильный результат, например: .... 4, 3, 2, 1, 0. Я думаю, проблема в том, что что-то не перекрашивается, когда оно называется ScrollWindow, но я не знаю, в чем проблема, поскольку я следил за книга.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)); 

     } 

ответ

3

Весь смысл ScrollWindow() является перемещение существующего содержимого окна без нуждающейся перекрашивать все. Основное предположение состоит в том, что перемещаемое содержимое не изменяется в результате действия прокрутки, и нужно раскрасить только «непокрытый» регион.

В вашем примере вы хотите изменений содержания (по перенумерации линии), а не только движения его. Это означает, что его нужно перерисовать, что ScrollWindow() в обработке ваших ключевых сообщений не вызывает, но InvalidateRect() в вашем обработчике WM_SIZE.

+0

Спасибо, Брайан. Поэтому, когда принимается второе сообщение клавиатуры, единственная строка внизу, показывающая 0, перемещается на одну строку выше, но все еще показывает 0, так как она не находится в «непокрытой» области, поэтому не перерисовывается, правильно? – user565739

+1

Точно. И появляется «новая» линия, потому что «непокрытый» регион недействителен, поэтому он окрашивается. В стороне, преимущество использования 'ScrollWindow()' несколько уменьшается, когда ваш 'WM_PAINT' все равно рисует, не принимая во внимание размер и расположение недопустимой области ... –

Смежные вопросы