Win32 - API - Input
[TOC]
입력
키보드
WM_CHAR
- 문자 입력시 발생하는 메시지
- 입력된 문자의 아스키 코드는 wParam으로 전달
- lParam으로는 반복 횟수, 스캔 코드, 확장키, 이전키 상태 플래그 등의 정보가 들어있다.
case WM_CHAR:
{
g_str[g_strIndex++] = wParam;
InvalidateRect(NULL, NULL, TRUE);
}
WM_KEYDOWN
- 문자 이외의 키를 입력받을 수 있다.
- wParam에 문자 코드 대신 가상 키코드가 들어있다.
- 가상 키코드
- 키보드의 종류에 상관없이 카를 입력받기 위한 코드값
- 현재 키보드에 없는 키값도 미리 정의되어있다.
- VK_SELECT, VK_EXECUTE, VK_HELP
- ~ F16
- 윈도우를 다른 시스템에 이식하더라도 키 코드를 사용할 수 있게 하기 위함
- 숫자 및 영문자의 가상 키코드는 아스키 코드와 같다
- lParam으로 전달되는 값은 WM_CHAR와 동일
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_LEFT:
g_movableTextPosition.x -= 1;
break;
case VK_RIGHT:
g_movableTextPosition.x += 1;
break;
case VK_UP:
g_movableTextPosition.y -= 1;
break;
case VK_DOWN:
g_movableTextPosition.y += 1;
break;
default:
break;
}
InvalidateRect(hWnd, NULL, TRUE);
}
WM_KEYUP
- 키가 떨어질 때 발생
- wParam, lParam의 의미는 WM_KEYDOWN과 동일
GetAsyncKeyState()
- 실시간으로 키 입력을 체크
- 메시지 큐에 저장되는 키 메시지의 단점을 보완
- 리턴값
- 키 눌림이 있으면 최상위 비트(MSB)가 1.
- Caps Lock, Scroll Lock 같은 토글키가 On 상태이면 최하위 비트(LSB)가 1.
GetAsyncKeyState() 리턴값
? 아래 테이블 검증
| 값 | 설명 |
|---|---|
| 0x0000 | 이전에 누른 적이 없고 호출 시점에도 눌려있지 않은 상태 |
| 0x0001 | 이전에 누른 적이 있고 호출 시점에는 눌려있지 않은 상태 |
| 0x8000 | 이전에 누른 적이 없고 호출 시점에는 눌려있는 상태 |
| 0x8001 | 이전에 누른 적이 있고 호출 시점에도 눌려있는 상태 |
if (GetAsyncKeyState(VK_F1) & 0x8000) {
g_bF1KeyDown = TRUE;
}
else {
g_bF1KeyDown = FALSE;
}
마우스
WM_MOUSEMOVE
- 마우스 이동 시 발생
- 마우스 좌표는 lParam으로 전달
- LOWORD(lParam) : x좌표
- HIWORD(lParam) : y좌표
- 현재 눌린 키에 대한 정보는 wParam을 다음의 매크로와 비교
- MK_LBUTTON, MK_RBUTTON, MK_SHIFT, …
// 드래그하여 사각형 그리기 방법 1.
if (g_bDragging) { // WM_LBUTTONDOWN에서 TRUE로 만든다.
WORD x = LOWORD(lParam);
WORD y = HIWORD(lParam);
HDC hdc = GetDC(hWnd);
Rectangle(hdc, g_dragStartPosition.x, g_dragStartPosition.y, x, y);
ReleaseDC(hWnd, hdc);
}
// 드래그하여 사각형 그리기 방법 2.
if (wParam == MK_LBUTTON) {
WORD x = LOWORD(lParam);
WORD y = HIWORD(lParam);
HDC hdc = GetDC(hWnd);
Rectangle(hdc, g_dragStartPosition.x, g_dragStartPosition.y, x, y);
ReleaseDC(hWnd, hdc);
}
타이머
- WM_TIMER 메시지를 지정한 시간 간격마다 발생시킨다.
- 여러개의 타이머를 설정할 수 있고 각 타이머는 아이디로 구분한다.
- wParam가 타이머의 아이디값이다.
- KillTimer() 함수로 타이머를 종료시킨다.
case WM_CREATE: // 윈도우가 처음 생성됐을 때 발생
SetTimer(hWnd, 1, 1000, NULL);
SetTimer(hWnd, 2, 2000, NULL);
break;
case WM_TIMER:
{
switch (wParam)
{
case 1:
g_nTimerCount1++;
break;
case 2:
g_nTimerCount2++;
break;
default:
break;
}
InvalidateRect(hWnd, NULL, false);
}
break;
case WM_DESTROY:
KillTimer(1);
KillTimer(2);
PostQuitMessage(0); // GetMessage() 함수가 0을 반환하게 된다.
break;
타이머 콜백함수
- WM_TIMER 메시지 대신 지정한 콜백함수가 호출된다.
SetTimer(hWnd, 2, 2000, TimerProc);
VOID CALLBACK TimerProc(HWND hWnd, UINT message, UINT_PTR id, DWORD time) {
g_nTimerCount2++;
}