2017-01-08 5 views
-2

Недавно я решил узнать немного WinApi, но я попал в ловушку. Я хочу показать массаж в моем окне после нажатия клавиши, но он, похоже, не работает. Если я нажимаю клавишу несколько раз, или если я ее удерживаю, все равно ничего не происходит. Можете ли вы сказать мне, что я делаю неправильно?winapi не реагирует на нажатие клавиши

Это полный код:

#include <windows.h> 
#include <string.h> 
#include <stdlib.h> 
#include <tchar.h> 

LRESULT CALLBACK WndProc (HWND hwnd, 
          UINT uMsg, 
          WPARAM wParam, 
          LPARAM lParam) 
{ 
    PAINTSTRUCT ps; 
    HDC hdc; 
    LPCWSTR display_str = L"hello"; 
    switch(uMsg) 
    { 
     case WM_PAINT: 
      hdc = BeginPaint(hwnd, &ps); 
      if(GetAsyncKeyState(VK_UP)) 
      { 
      TextOut(hdc, 
        15, 15, 
        display_str, 
        _tcslen(display_str)); 
      } 
      EndPaint(hwnd, &ps); 
      break; 

     case WM_CLOSE: 
      DestroyWindow(hwnd); 
      break; 
     case WM_DESTROY: 
      PostQuitMessage(0); 
      break; 
     default: 
      return DefWindowProc(hwnd, uMsg, wParam, lParam); 
    } 
    return 0; 
} 

int WINAPI WinMain(HINSTANCE hInstance, 
        HINSTANCE hPrevInstance, 
        LPSTR lpCmdLine, 
        int nCmdShow) 
{ 
    HWND hwnd; 
    MSG uMsg; 
    HINSTANCE hInst; 
    WNDCLASSEX wcex; 
    LPCWSTR class_name = L"myWindowClass"; 

    wcex.cbSize   = sizeof(WNDCLASSEX); 
    wcex.style   = CS_HREDRAW | CS_VREDRAW; 
    wcex.lpfnWndProc = WndProc; 
    wcex.cbClsExtra  = 0; 
    wcex.cbWndExtra  = 0; 
    wcex.hInstance  = hInstance; 
    wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 
    wcex.hCursor  = LoadCursor(NULL, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wcex.lpszMenuName = NULL; 
    wcex.lpszClassName = class_name; 
    wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 

    if(!RegisterClassEx(&wcex)) 
    { 
     MessageBox(NULL, L"Call to RegisterClassEx failed!", L"Win32 Guided Tour!", 
     MB_ICONEXCLAMATION | MB_OK); 
     return 0; 
    } 

    hInst = hInstance; 

    hwnd = CreateWindowEx(
     NULL, 
     class_name, 
     L"Test", 
     WS_OVERLAPPEDWINDOW, 
     200, 200, 
     740, 540, 
     NULL, 
     NULL, 
     hInstance, 
     NULL 
     ); 

    if(!hwnd) 
    { 
     MessageBox(NULL, L"Window Creation Failed!", L"Error!", 
     MB_ICONEXCLAMATION | MB_OK); 
     return 0; 
    } 

    ShowWindow(hwnd, nCmdShow); 
    UpdateWindow(hwnd); 

    while(GetMessage(&uMsg, NULL, 0, 0) > 0) 
    { 
     TranslateMessage(&uMsg); 
     DispatchMessage(&uMsg); 
    } 
    return uMsg.wParam; 
} 
+1

Кажется, что вы не обрабатываете сообщения с клавиатуры. –

+3

Windows не раз краскает окно, как игра или монитор, делает каждую 1/60 секунды. Windows только рисует окно, когда это необходимо. Ваш текущий подход не будет работать. Вам нужно будет искать сообщения на клавиатуре и попросить их нарисовать, а не наоборот. Обязательно прочитайте введение MSDN в модель окраски Windows. – andlabs

+2

Вам нужна [эта книга] (https://www.amazon.com/Programming-Windows®-Fifth-Developer-Reference/dp/157231995X). Используемые копии дешевы. Получите один, если вы хотите изучить Windows API. Шутки в сторону. –

ответ

1

для Windows посылает сообщение WM_KEYDOWN при нажатии клавиши. В WndProc обработайте сообщение WM_KEYDOWN, вызовите InvalidateRect с клиентом rect окна и нарисуйте текст, который хотите отобразить в обработчике сообщений WM_PAINT.

+2

Вы не рисуете текст в обработчике сообщения 'WM_KEYDOWN'. Вы аннулируете часть окна, которое должно быть перекрашено в ответ на нажатие клавиши. Вся картина выполняется в обработчике 'WM_PAINT'. – IInspectable

+0

@ Изначально исправлено это, спасибо. – army007