2014-11-18 2 views
-1
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 

HDC    hdc; 
PAINTSTRUCT  ps; 
TCHAR   szBuffer[1]; 



switch (message) 
{ 
case WM_CHAR: 
    szBuffer[1] = (TCHAR) wParam; 
    cout << wParam << " " << szBuffer[1] << " "; 

    break; 

case WM_PAINT: 
    InvalidateRect(hwnd, NULL, TRUE); 
    hdc = BeginPaint(hwnd, &ps); 
    SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT)); 
    TextOut(hdc, 1, 1, szBuffer, 1); 
    EndPaint(hwnd, &ps); 
    return 0; 

Привет всем, Я пытаюсь запустить приведенный выше код и просто распечатать одну букву за раз в моем окне. Тем не менее, я не могу заставить символы появляться в окне с помощью функции TextOut, но я могу отображать символы в окне терминала. Я новичок в WinApi, и я потерялся!textout winapi с сообщениями клавиатуры

благодарит заранее!

+1

'static TCHAR szBuffer [2];' ... 'szBuffer [0] = (TCHAR) wParam; szBuffer [1] = '\ 0'; ' –

+0

@JonathanPotter - это радость текстовых API-интерфейсов GDI, которые не только не требуют строк с нулевым символом, но также не позволяют их полностью ... (Действительно, я бы хотел, чтобы функции accept -1 означает нуль-завершение, как функции преобразования набора символов: |) Я предполагаю, что этот человек исходит из какого-то другого языка программирования (один с индексированием на основе 1), поэтому я попытался отразить это в своем ответе:/Но да, изучение строк с нулевым завершением может быть важно. – andlabs

+2

У вас нет вызова InvalidateRect() внутри вашего обработчика WM_PAINT. InvalidateRect() - это то, что вы вызываете, чтобы заставить WM_PAINT вызываться в первую очередь. Однако вы можете поместить его в обработчик WM_CHAR. –

ответ

3

Ваш szBuffer является локальным для WndProc() и по умолчанию локальные переменные в C имеют автоматическое хранение: каждый раз, когда ваш WndProc() называется новый szBuffer создается, так что к тому времени ваш WM_PAINT достигнуто, то, что было набрано WM_CHAR был потерян. Вам нужно будет хранить szBuffer где-то в другом месте, например, за пределами WndProc(), или объявить его как static, который будет хранить буфер вокруг (но остерегайтесь того, что статическое хранилище НЕ безопасно для рекурсии).

Также в C первый элемент массива имеет индекс 0, а не 1; строка szBuffer[1] = (TCHAR) wParam; должна быть szBuffer[0] = (TCHAR) wParam;, чтобы сделать то, что вы хотите.


Поскольку я бегу на предположении, вы знакомы с C, см комментарий Джонатана Поттера о том, дополнительный символ в ваших строк, значение которых равно нулю (не код символа для цифры ноль, но численное значение 0, или '\0' или L'\0'). В то время как TextOut() и другие функции рисования текста GDI не используют эти строки с нулевым символом, все остальное в C делает. Осторожно.


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