WinAPI: WM_CHAR

키보드로부터 입력이 발생했을 경우 Windows는 포커스를 가진 프로그램에게 메시지(WM_CHAR)를 보내줍니다.

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
static char str[256];
int len;
switch (iMessage) {
case WM_CHAR:
len = strlen(str);
str[len] = (TCHAR)wParam;
str[len + 1] = 0;
InvalidateRect(hWnd, NULL, FALSE);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd,&ps);
TextOut(hdc, 100, 100, str, strlen(str));
EndPaint(hWnd, &ps);
return 0;
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

 이 소스를 실행하면 키보드로 입력한 문자들이 화면 상단에 출력되는 것을 볼 수 있습니다. 입력된 문자들을 바로 출력하지 않고 반드시 문자열에 모아 두어야 하는 이유는 입력 발생 시점과 출력 시점이 분리되어 있기 때문입니다. 입력 시점은 WM_CHAR가 발생했을 때이며 출력은 WM_PAINT에서 처리합니다. 하지만 윈도우는 화면을 다시 그릴 준비를 항상 해 두어야 하며 모든 출력은 WM_PAINT에서 하도록 되어 있습니다.

 wParam은 입력된 문자의 아스키 코드를 전달하는 역할을 합니다. lParam에는 비트별로 복잡한 정보가 전달됩니다.  WM_CHAR 메시지에서 lParam의 정보들을 사용해야 할 경우는 드뭅니다.
0~15 : 반복 카운트
16~23 : 스캔 코드
24 : 오른쪽 Alt, 오른쪽 Ctrl 등 101키에만 있는 확장키가 눌러졌을 경우 1이 됩니다.
25~28 : 미사용
29 : Alt키가 눌리면 1
30 : 메시지가 보내지기 전에 키가 눌러져 있었으면 1
31 : 키가 놓아지면 1, 눌리면 0

 WM_PAINT는 강제로 호출해야 합니다. InvalidateRect 함수를 호출하여 WM_PAINT를 호출합니다.

댓글