키보드는 다음을 비롯한 여러 가지 유형의 입력에 사용됩니다.
- 문자 입력입니다. 사용자가 문서 또는 편집 상자에 입력하는 텍스트입니다.
- 키보드 단축키. 애플리케이션 함수를 호출하는 키 스트로크; 예를 들어 Ctrl+O를 사용하여 파일을 엽니다.
- 시스템 명령. 시스템 함수를 호출하는 키 스트로크; 예를 들어 Alt + TAB을 사용하여 창을 전환합니다.
키보드 입력에 대해 생각할 때 키 스트로크가 문자와 동일하지 않다는 점을 기억해야 합니다. 예를 들어 A 키를 누르면 다음 문자가 발생할 수 있습니다.
- a
- A
- á(키보드가 결합 악센트를 지원하는 경우)
또한 ALT 키를 누르면, A 키를 눌렀을 때 시스템에서는 ALT+A를 생성하지만, 이를 문자로 처리하지 않고 시스템 명령으로 처리합니다.
키 코드
키를 누르면 하드웨어에서 검사 코드생성합니다. 스캔 코드는 키보드마다 다르며 키 업 및 키 다운 이벤트에 대한 별도의 검사 코드가 있습니다. 스캔 코드는 거의 신경 쓰지 않을 것입니다. 키보드 드라이버는 스캔 코드를 가상 키 코드로 변환합니다. 가상 키 코드는 디바이스 독립적입니다. 키보드에서 A 키를 누르면 동일한 가상 키 코드가 생성됩니다.
일반적으로 가상 키 코드는 ASCII 코드 또는 다른 문자 인코딩 표준에 해당하지 않습니다. 동일한 키가 서로 다른 문자(a, A, á)를 생성할 수 있고 함수 키와 같은 일부 키가 문자에 해당하지 않기 때문에 이는 분명합니다.
즉, 다음 가상 키 코드는 ASCII에 해당하는 코드에 매핑됩니다.
- 0~9개 키 = ASCII '0' – '9'(0x30 – 0x39)
- A 부터 Z 키 = ASCII 'A' – 'Z' (0x41 – 0x5A)
어떤 면에서 이 매핑은 설명된 이유로 가상 키 코드를 문자로 간주해서는 안 되므로 불행한 일입니다.
헤더 파일 WinUser.h는 대부분의 가상 키 코드에 대한 상수를 정의합니다. 예를 들어 왼쪽 화살표 키의 가상 키 코드는 VK_LEFT(0x25)입니다. 가상 키 코드의 전체 목록은 Virtual-Key 코드참조하세요. ASCII 값과 일치하는 가상 키 코드에 대한 상수는 정의되지 않습니다. 예를 들어 A 키에 대한 가상 키 코드는 0x41 있지만 VK_A이름이 지정된 상수는 없습니다. 대신 숫자 값을 사용합니다.
Key-Down 및 Key-Up 메시지
키를 누르면 키보드 포커스가 있는 창에 다음 메시지 중 하나가 표시됩니다.
WM_SYSKEYDOWN 메시지는 시스템 명령을 호출하는 키 스트로크인 시스템 키나타냅니다. 시스템 키에는 두 가지 유형이 있습니다.
- ALT + 모든 키
- F10
F10 키는 창의 메뉴 모음을 활성화합니다. 다양한 ALT 키 조합은 시스템 명령을 호출합니다. 예를 들어 ALT + TAB은 새 창으로 전환됩니다. 또한 창에 메뉴가 있는 경우 ALT 키를 사용하여 메뉴 항목을 활성화할 수 있습니다. 일부 ALT 키 조합은 아무 것도 수행하지 않습니다.
다른 모든 키 스트로크는 비시스템 키로 간주되며 WM_KEYDOWN 메시지를 생성합니다. 여기에는 F10 이외의 함수 키가 포함됩니다.
키를 해제하면 시스템에서 해당 키 업 메시지를 보냅니다.
키보드의 반복 기능을 시작할 수 있을 만큼 긴 키를 누른 경우 시스템에서 여러 키 다운 메시지를 보낸 다음 단일 키 업 메시지를 보냅니다.
지금까지 설명한 4개의 키보드 메시지에서 wParam 매개 변수에는 키의 가상 키 코드가 포함되어 있습니다. lParam 매개 변수에는 32비트로 압축된 일부 기타 정보가 포함되어 있습니다. 일반적으로 lParam에서 정보가 필요하지 않습니다. 유용할 수 있는 하나의 플래그는 비트 30, 반복된 키 다운 메시지에 대해 1로 설정된 "이전 키 상태" 플래그입니다.
이름에서 알 수 있듯이 시스템 키 스트로크는 주로 운영 체제에서 사용하기 위한 것입니다. WM_SYSKEYDOWN 메시지를 가로채면 나중에 DefWindowProc 호출합니다. 그렇지 않으면 운영 체제가 명령을 처리하지 못하도록 차단합니다.
문자 메시지
키 스트로크는 우리가 모듈 1에서 처음 본 TranslateMessage 함수에 의해 문자로 변환됩니다. 이 함수는 키 다운 메시지를 검사하고 문자로 변환합니다. 생성된 각 문자에 대해 TranslateMessage 함수는 WM_CHAR 또는 WM_SYSCHAR 메시지를 창의 메시지 큐에 배치합니다. 메시지의 wParam 매개 변수에는 UTF-16 문자가 포함됩니다.
짐작할 수 있듯이 WM_CHAR 메시지는 WM_KEYDOWN 메시지에서 생성되고 WM_SYSCHAR 메시지는 WM_SYSKEYDOWN 메시지에서 생성됩니다. 예를 들어 사용자가 Shift 키를 누른 다음 A 키를 누르는 경우를 가정해 보겠습니다. 표준 키보드 레이아웃을 가정하면 다음과 같은 메시지 시퀀스가 표시됩니다.
WM_KEYDOWN: 쉬프트
WM_KEYDOWN: A
WM_CHAR: 'A'
반면에 ALT + P 조합은 다음을 생성합니다.
WM_SYSKEYDOWN: VK_MENU
WM_SYSKEYDOWN: 0x50
WM_SYSCHAR: 'p'
WM_SYSKEYUP: 0x50
WM_KEYUP: VK_MENU
(Alt 키의 가상 키 코드는 기록상의 이유로 VK_MENU 이름이 지정됩니다.)
WM_SYSCHAR 메시지는 시스템 문자를 나타냅니다. WM_SYSKEYDOWN마찬가지로 일반적으로 이 메시지를 DefWindowProc직접 전달해야 합니다. 그렇지 않으면 표준 시스템 명령을 방해할 수 있습니다. 특히 WM_SYSCHAR 사용자가 입력한 텍스트로 취급하지 마세요.
WM_CHAR 메시지는 일반적으로 문자 입력으로 생각하는 것입니다. 문자의 데이터 형식은 utF-16 유니코드 문자를 나타내는 wchar_t. 문자 입력에는 ASCII 범위 외부의 문자, 특히 미국 외부에서 일반적으로 사용되는 키보드 레이아웃이 포함될 수 있습니다. 지역 키보드를 설치한 다음 화상 키보드 기능을 사용하여 다양한 키보드 레이아웃을 사용해 볼 수 있습니다.
사용자는 IME(입력 방법 편집기)를 설치하여 표준 키보드를 사용하여 일본어 문자와 같은 복잡한 스크립트를 입력할 수도 있습니다. 예를 들어 일본어 IME를 사용하여 가타카나 문자 (ka)를 입력하면 다음 메시지가 표시될 수 있습니다.
WM_KEYDOWN: VK_PROCESSKEY(IME 프로세스 키)
WM_KEYUP: 0x4B
WM_KEYDOWN: VK_PROCESSKEY
WM_KEYUP: 0x41
WM_KEYDOWN: VK_PROCESSKEY
WM_CHAR: カ
WM_KEYUP: VK_RETURN
일부 Ctrl 키 조합은 ASCII 컨트롤 문자로 변환됩니다. 예를 들어 CTRL+A는 ASCII CTRL-A(SOH) 문자(ASCII 값 0x01)로 변환됩니다. 텍스트 입력의 경우 일반적으로 컨트롤 문자를 필터링해야 합니다. 또한 WM_CHAR 사용하여 바로 가기 키를 구현하지 않도록 합니다. 대신 WM_KEYDOWN 메시지를 사용합니다. 또는 더 나은 액셀러레이터 테이블을 사용합니다. 가속기 테이블은 가속기 테이블다음 항목에서 설명합니다.
다음 코드는 디버거에 기본 키보드 메시지를 표시합니다. 다양한 키 입력 조합으로 플레이하고 생성되는 메시지를 확인합니다.
메모
wchar.h를 포함해야 합니다. 그렇지 않으면 swprintf_s 정의되지 않습니다.
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
wchar_t msg[32];
switch (uMsg)
{
case WM_SYSKEYDOWN:
swprintf_s(msg, L"WM_SYSKEYDOWN: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_SYSCHAR:
swprintf_s(msg, L"WM_SYSCHAR: %c\n", (wchar_t)wParam);
OutputDebugString(msg);
break;
case WM_SYSKEYUP:
swprintf_s(msg, L"WM_SYSKEYUP: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_KEYDOWN:
swprintf_s(msg, L"WM_KEYDOWN: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_KEYUP:
swprintf_s(msg, L"WM_KEYUP: 0x%x\n", wParam);
OutputDebugString(msg);
break;
case WM_CHAR:
swprintf_s(msg, L"WM_CHAR: %c\n", (wchar_t)wParam);
OutputDebugString(msg);
break;
/* Handle other messages (not shown) */
}
return DefWindowProc(m_hwnd, uMsg, wParam, lParam);
}
기타 키보드 메시지
일부 다른 키보드 메시지는 대부분의 애플리케이션에서 무시해도 됩니다.
- WM_DEADCHAR 메시지는 부호와 같은 결합 키에 대해 전송됩니다. 예를 들어 스페인어 키보드에서 악센트(')를 입력한 다음 E를 입력하면 문자 é가 생성됩니다. 악센트 문자에 대해 WM_DEADCHAR 메시지가 전송됩니다.
- WM_UNICHAR 메시지는 사용되지 않습니다. ANSI 프로그램에서 유니코드 문자 입력을 받을 수 있습니다.
- WM_IME_CHAR 문자는 IME가 키 입력 시퀀스를 문자로 변환할 때 전송됩니다. 일반적인 WM_CHAR 메시지 외에 전송됩니다.
키보드 상태
키보드 메시지는 이벤트 기반입니다. 즉, 키 누르기와 같이 흥미로운 일이 발생하면 메시지가 표시되고 방금 무슨 일이 일어났는지 알려줍니다. 그러나 GetKeyState 함수를 호출하여 언제든지 키의 상태를 테스트할 수도 있습니다.
예를 들어 마우스 왼쪽 클릭 + ALT 키의 조합을 검색하는 방법을 고려합니다. 키 입력 메시지를 수신 대기하고 플래그를 저장하여 ALT 키의 상태를 추적할 수 있지만, GetKeyState를 통해 그 수고를 덜 수 있습니다. WM_LBUTTONDOWN 메시지를 받으면 다음과 같이 GetKeyState 호출하면 됩니다.
if (GetKeyState(VK_MENU) & 0x8000)
{
// ALT key is down.
}
GetKeyState 메시지는 가상 키 코드를 입력으로 사용하고 비트 플래그 집합(실제로는 두 개의 플래그)을 반환합니다. 0x8000 값에는 키를 현재 누르고 있는지 여부를 테스트하는 비트 플래그가 포함됩니다.
대부분의 키보드에는 왼쪽과 오른쪽의 두 개의 ALT 키가 있습니다. 이전 예제에서는 둘 중 하나가 눌렸는지를 테스트합니다. GetKeyState사용하여 Alt, Shift 또는 Ctrl 키의 왼쪽 및 오른쪽 인스턴스를 구분할 수도 있습니다. 예를 들어 다음 코드는 올바른 ALT 키를 누르는지 테스트합니다.
if (GetKeyState(VK_RMENU) & 0x8000)
{
// Right ALT key is down.
}
GetKeyState 함수는 가상 키보드 상태를 보고하기 때문에 흥미롭습니다. 이 가상 상태는 메시지 큐의 내용을 기반으로 하며 큐에서 메시지를 제거할 때 업데이트됩니다. 프로그램에서 창 메시지를 처리할 때 getKeyState 각 메시지가 큐에 대기될 때 키보드의 스냅샷을 제공합니다. 예를 들어 큐의 마지막 메시지가 WM_LBUTTONDOWN경우 getKeyState 사용자가 마우스 단추를 클릭한 순간에 키보드 상태를 보고합니다.
GetKeyState메시지 큐를 기반으로 하므로 다른 프로그램으로 전송된 키보드 입력도 무시됩니다. 사용자가 다른 프로그램으로 전환하면 해당 프로그램으로 전송되는 키 누름은 GetKeyState무시됩니다. 키보드의 즉각적인 물리적 상태를 알고 싶다면 getAsyncKeyState함수가 있습니다. 그러나 대부분의 UI 코드에서 올바른 함수는 GetKeyState .
다음