액셀러레이터 키 테이블
애플리케이션은 파일 열기 명령에 대한 Ctrl+O와 같은 바로 가기 키를 정의하는 경우가 많습니다. 개별 WM_KEYDOWN 메시지를 처리하여 바로 가기 키를 구현할 수 있지만 액셀러레이터 키 테이블은 다음과 같은 더 나은 솔루션을 제공합니다.
- 코딩이 덜 필요합니다.
- 모든 바로 가기를 하나의 데이터 파일로 통합합니다.
- 다른 언어로 지역화할 수 있습니다.
- 바로 가기 및 메뉴 명령에서 동일한 애플리케이션 논리를 사용할 수 있습니다.
액셀러레이터 키 테이블은 Ctrl+O와 같은 키보드 조합을 애플리케이션 명령에 매핑하는 데이터 리소스입니다. 액셀러레이터 키 테이블을 사용하는 방법을 알아보기 전에 리소스를 빠르게 소개하려고 합니다. 리소스는 애플리케이션 이진(EXE 또는 DLL)에 기본 제공되는 데이터 Blob입니다. 리소스는 메뉴, 커서, 아이콘, 이미지, 텍스트 문자열 또는 사용자 지정 애플리케이션 데이터와 같이 애플리케이션에 필요한 데이터를 저장합니다. 애플리케이션은 런타임에 이진 파일에서 리소스 데이터를 로드합니다. 이진 파일에 리소스를 포함하려면 다음을 수행합니다.
- 리소스 정의(.rc) 파일을 만듭니다. 이 파일은 리소스 유형과 해당 식별자를 정의합니다. 리소스 정의 파일에는 다른 파일에 대한 참조가 포함될 수 있습니다. 예를 들어 아이콘 리소스는 .rc 파일에 선언되지만 아이콘 이미지는 별도의 파일에 저장됩니다.
- Microsoft Windows RC(리소스 컴파일러)를 사용하여 리소스 정의 파일을 컴파일된 리소스(.res) 파일로 컴파일합니다. RC 컴파일러는 Visual Studio 및 Windows SDK와 함께 제공됩니다.
- 컴파일된 리소스 파일을 이진 파일에 연결합니다.
이러한 단계는 코드 파일의 컴파일/연결 프로세스와 거의 동일합니다. Visual Studio는 리소스를 쉽게 만들고 수정할 수 있는 리소스 편집기 집합을 제공합니다. (이러한 도구는 Visual Studio의 Express 버전에서는 사용할 수 없습니다.) 그러나 .rc 파일은 단순히 텍스트 파일이며 구문은 MSDN에 문서화되어 있으므로 텍스트 편집기를 사용하여 .rc 파일을 만들 수 있습니다. 자세한 내용은 리소스 파일 정보를 참조하세요.
액셀러레이터 키 테이블 정의
액셀러레이터 키 테이블은 바로 가기 키의 테이블입니다. 각 바로 가기는 다음으로 정의됩니다.
- 숫자 식별자. 이 숫자는 바로 가기에서 호출할 애플리케이션 명령을 식별합니다.
- 바로 가기의 ASCII 문자 또는 가상 키 코드
- 선택적 한정자 키: Alt, Shift 또는 Ctrl.
액셀러레이터 키 테이블 자체에는 애플리케이션 리소스 목록의 테이블을 식별하는 숫자 식별자가 있습니다. 간단한 그리기 프로그램에 대한 액셀러레이터 키 테이블을 만들어 보겠습니다. 이 프로그램에는 그리기 모드와 선택 모드의 두 가지 모드가 있습니다. 그리기 모드에서 사용자는 셰이프를 그릴 수 있습니다. 선택 모드에서 사용자는 셰이프를 선택할 수 있습니다. 이 프로그램을 위해 다음 바로 가기 키를 정의하려고 합니다.
바로 가기 | 명령 |
---|---|
Ctrl+M | 모드 간을 전환합니다. |
F1 | 그리기 모드로 전환합니다. |
F2 | 선택 모드로 전환합니다. |
먼저 테이블 및 애플리케이션 명령에 대한 숫자 식별자를 정의합니다. 이러한 값은 임의 값입니다. 헤더 파일에서 정의하여 식별자에 기호 상수를 할당할 수 있습니다. 예를 들어 다음과 같습니다.
#define IDR_ACCEL1 101
#define ID_TOGGLE_MODE 40002
#define ID_DRAW_MODE 40003
#define ID_SELECT_MODE 40004
이 예제에서 값 IDR_ACCEL1
은 액셀러레이터 키 테이블을 식별하고 다음 세 개의 상수는 애플리케이션 명령을 정의합니다. 규칙에 따라 리소스 상수를 정의하는 헤더 파일 이름이 resource.h로 지정됩니다. 다음 목록에서는 리소스 정의 파일을 보여 줍니다.
#include "resource.h"
IDR_ACCEL1 ACCELERATORS
{
0x4D, ID_TOGGLE_MODE, VIRTKEY, CONTROL // ctrl-M
0x70, ID_DRAW_MODE, VIRTKEY // F1
0x71, ID_SELECT_MODE, VIRTKEY // F2
}
액셀러레이터 키 바로 가기는 중괄호로 묶어 정의합니다. 각 바로 가기에는 다음 항목이 포함됩니다.
- 바로 가기를 호출하는 가상 키 코드 또는 ASCII 문자
- 애플리케이션 명령 이 예제에서는 기호 상수가 사용됩니다. 리소스 정의 파일에는 이러한 상수가 정의된 resource.h가 포함됩니다.
- VIRTKEY 키워드는 첫 번째 항목이 가상 키 코드임을 의미합니다. 다른 옵션은 ASCII 문자를 사용하는 것입니다.
- 선택적 한정자: Alt, Ctrl 또는 Shift.
바로 가기에 ASCII 문자를 사용하는 경우 소문자는 대문자와 다른 바로 가기가 됩니다. 예를 들어 'a'를 입력하면 'A'를 입력하는 것과 다른 명령이 호출될 수 있습니다. 이 경우 사용자에게 혼동을 줄 수 있으므로 일반적으로 바로 가기에 ASCII 문자 대신 가상 키 코드를 사용하는 것이 좋습니다.
액셀러레이터 키 테이블 로드
프로그램에서 사용하려면 먼저 액셀러레이터 키 테이블용 리소스를 로드해야 합니다. 액셀러레이터 키 테이블을 로드하려면 LoadAccelerators 함수를 호출합니다.
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCEL1));
메시지 루프를 시작하기 전에 이 함수를 호출합니다. 첫 번째 매개 변수는 모듈에 대한 핸들입니다. (이 매개 변수는 WinMain 함수에 전달됩니다. 자세한 내용은 WinMain: 애플리케이션 진입점을 참조하세요.) 두 번째 매개 변수는 리소스 식별자입니다. 이 함수는 리소스에 대한 핸들을 반환합니다. 다시 말하지만 핸들은 시스템에서 관리하는 개체를 참조하는 불투명 형식입니다. 이 함수가 실패하면 NULL을 반환합니다.
DestroyAcceleratorTable을 호출하여 액셀러레이터 키 테이블을 해제할 수 있습니다. 그러나 프로그램이 종료되면 시스템에서 테이블을 자동으로 해제하므로 테이블을 다른 테이블로 바꾸는 경우에만 이 함수를 호출하면 됩니다. 이 예제는 사용자 편집 가능한 액셀러레이터 키 만들기 항목에 나와 있습니다.
키 입력을 명령으로 변환
액셀러레이터 키 테이블은 키 입력을 WM_COMMAND 메시지로 변환하여 작동합니다.
WM_COMMAND의 wParam 매개 변수에는 명령의 숫자 식별자가 포함됩니다. 예를 들어 이전에 표시된 테이블을 사용하여 키 입력 Ctrl+M은 값이 ID_TOGGLE_MODE
인 WM_COMMAND 메시지로 변환됩니다. 이렇게 하려면 메시지 루프를 다음으로 변경합니다.
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(win.Window(), hAccel, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
이 코드는 메시지 루프 내에 TranslateAccelerator 함수에 대한 호출을 추가합니다. TranslateAccelerator 함수는 각 창 메시지를 검사하여 키 누르기 메시지를 찾습니다. 사용자가 액셀러레이터 키 테이블에 나열된 키 조합 중 하나를 누르면 TranslateAccelerator는 창에 WM_COMMAND 메시지를 보냅니다. 이 함수는 창 프로시저를 직접 호출하여 WM_COMMAND를 보냅니다. TranslateAccelerator가 키 입력을 성공적으로 변환하면 함수는 0이 아닌 값을 반환합니다. 즉, 메시지에 대한 일반 처리를 건너뛰어야 합니다. 그렇지 않으면 TranslateAccelerator가 0을 반환합니다. 이 경우 창 메시지를 정상적으로 TranslateMessage 및 DispatchMessage에 전달합니다.
그리기 프로그램에서 WM_COMMAND 메시지를 처리하는 방법은 다음과 같습니다.
case WM_COMMAND:
switch (LOWORD(wParam))
{
case ID_DRAW_MODE:
SetMode(DrawMode);
break;
case ID_SELECT_MODE:
SetMode(SelectMode);
break;
case ID_TOGGLE_MODE:
if (mode == DrawMode)
{
SetMode(SelectMode);
}
else
{
SetMode(DrawMode);
}
break;
}
return 0;
이 코드는 SetMode
가 두 모드 간에 전환하기 위해 애플리케이션에서 정의한 함수라고 가정합니다. 각 명령을 처리하는 방법에 대한 세부 정보는 프로그램에 따라 다릅니다.
다음