입력 처리 클릭과 키보드로 창 반응시키기
입력 처리는 “메시지를 받아 상태를 바꾸고, 다시 그린다”는 흐름으로 동작합니다. 이 구조를 이해하면 클릭이나 키 입력에 따라 화면이 변하는 프로그램을 만들 수 있습니다.
Hello World까지 출력했다면 이런 생각이 들 수 있습니다. “이 창은 왜 아무 반응이 없을까?” 실제 프로그램이라면 클릭하거나 키를 눌렀을 때 화면이 바뀌어야 자연스럽게 느껴집니다. 이번 단계에서는 WinAPI 창이 사용자 입력에 반응하고, 그 결과를 화면에 반영하는 흐름까지 이어서 만들어보겠습니다.
Hello World 다음에는 왜 입력 처리를 배워야 할까?
WinAPI 프로그램은 입력을 처리해야 비로소 “동작하는 프로그램”처럼 보입니다.
이전 단계에서는 WM_PAINT 메시지를 통해 텍스트를 화면에 출력했습니다. 하지만 이 상태는 단순히 보여주기만 하는 정적인 화면입니다. 사용자의 행동에 따라 변화가 있어야 실제 프로그램처럼 느껴집니다.
핵심 흐름은 다음과 같습니다.
- 입력 → 상태 변경 → 화면 다시 그리기
이 세 단계가 연결되면서 프로그램이 실제로 반응하기 시작합니다.
마우스 클릭 처리하기: WM_LBUTTONDOWN 이해하기
마우스를 클릭하면 WM_LBUTTONDOWN 메시지가 발생합니다. 이 메시지를 통해 클릭 위치와 이벤트를 처리할 수 있습니다.
case WM_LBUTTONDOWN:
{
int x = LOWORD(lParam);
int y = HIWORD(lParam);
g_text = L"마우스를 클릭했습니다";
InvalidateRect(hwnd, NULL, TRUE);
}
return 0;
lParam에는 클릭 좌표가 들어 있습니다. LOWORD와 HIWORD를 이용하면 X, Y 값을 분리할 수 있습니다.
중요한 점은 단순히 메시지를 처리하는 것이 아니라, 상태값을 바꾸고 화면 갱신까지 연결해야 한다는 것입니다.
키보드 입력 처리하기: WM_KEYDOWN 이해하기
키보드 입력은 WM_KEYDOWN 메시지로 처리합니다. 단, 창이 포커스를 가지고 있어야 메시지가 들어옵니다.
case WM_KEYDOWN:
{
if (wParam == 'A')
{
g_text = L"A 키를 눌렀습니다";
InvalidateRect(hwnd, NULL, TRUE);
}
}
return 0;
wParam에는 눌린 키 코드가 들어 있습니다. 이를 통해 특정 키 입력에 따라 동작을 다르게 만들 수 있습니다.
여기서 자주 발생하는 실수는 창에 포커스가 없는 상태에서 키 입력을 테스트하는 것입니다. 반드시 창을 한 번 클릭한 후 입력을 확인해야 합니다.
입력 결과를 화면에 반영하는 흐름 만들기
입력 처리의 핵심은 “값 변경과 화면 갱신은 별개”라는 점입니다.
다음 흐름을 반드시 기억해야 합니다.
- 입력 메시지 수신
- 상태값 변경 (예: g_text)
- InvalidateRect 호출
- WM_PAINT에서 다시 그림
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, g_text.c_str(), g_text.length());
EndPaint(hwnd, &ps);
}
return 0;
이 구조를 통해 클릭이나 키 입력에 따라 화면 텍스트가 바뀌는 프로그램을 만들 수 있습니다.
많은 초보자가 “값은 바뀌었는데 화면이 그대로인” 문제를 겪습니다. 대부분 InvalidateRect 호출이 빠진 경우입니다.
이 흐름을 이해하면 WinAPI에서 입력과 화면 출력이 어떻게 연결되는지 명확해집니다. 이제 단순 출력 프로그램을 넘어, 사용자와 상호작용하는 기본 형태를 갖춘 상태입니다.