지난시간에 마우스 이벤트에서 대해 알아보았는데 오늘은 마우스와 쌍을 이루는 Key 이벤트에 대해 알아보도록 하죠.
typedef struct _INPUT_RECORD {
WORD EventType;
union {
KEY_EVENT_RECORD KeyEvent;
MOUSE_EVENT_RECORD MouseEvent;
WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
MENU_EVENT_RECORD MenuEvent;
FOCUS_EVENT_RECORD FocusEvent;
} Event;
} INPUT_RECORD;
여기에서 KEY_EVENT_RECORD를 이용합니다.
typedef struct _KEY_EVENT_RECORD {
BOOL bKeyDown;
WORD wRepeatCount;
WORD wVirtualKeyCode;
WORD wVirtualScanCode;
union {
WCHAR UnicodeChar;
CHAR AsciiChar;
} uChar;
DWORD dwControlKeyState;
} KEY_EVENT_RECORD;
KEY_EVENT_RECORD에 각 정보들이 있는데 자세한 내용은 아래 참조 사이트를 보시기 바랍니다.
실습에 사용하는 것만 간단히 소개하면 다음과 같습니다.
이 두개만 사용합니다. 두개 정도만 하셔도 되고요. 추가로 아시면 좋은 것으로 dwControlKeyState은 지난시간에 살펴보았듯이 CAPSLOCK, ALT, CTRL, SHIFT 등의 키 상태 정보를 가지고 있습니다.
실습에서는 키 누름과 키값을 사용합니다.
참조 사이트에 가면 위 예제는 다음과 같이 나와 있네요.
printf("Key event: ");
if(keyEvent.bKeyDown) printf("key pressed\n");
else printf("key released\n");
위 예제에서는 단순히 키 누름 상태를 출력하는 예제인데 누른 키값을 확인하는 코딩이 추가로 있으면 좋을 것 같아서 아래와 같이 추가로 실험했네요.
printf("Key event: ");
if(keyEvent.bKeyDown){
if(keyEvent.wVirtualKeyCode==VK_ESCAPE) break;
else printf("%c\n",keyEvent.wVirtualKeyCode);
printf("key pressed\n");
}
else printf("key released\n");
먼저 키눌음을 bKeyDown으로 체크 한뒤에 어떤 키를 눌렀는지 wVirtualKeyCode로 추출하게 됩니다. 그리고 그 값을 printf()문으로 출력하게 됩니다. 이 코딩에서 ESC 키를 누르면 탈출하도록 break 명령문으로 if문을 설정했네요. 이 문장이 나중에 while(1)문으로 무한 루프를 돌때 빠져나올 수 있게 하기 위해서 사용합니다.
getch() 함수를 이용한 방법이 있습니다. 그리고 키가 눌렀는지 확인하는데 conio.h에서 제공되는 kbhit() 함수를 사용합니다. 제가 자주 사용하는 방법입니다.
if(kbhit()){
ch=getch();
printf("%c\n",ch);
}
이렇게 키가 눌러졌는지 확인하고 그 키값을 gech()로읽어와서 printf()문으로 출력합니다.
이제 두가지 방법을 실제 코딩해보고 그 결과를 살펴보도록 하죠.
[소스1]
#include
int main(int argc, char *argv[]){
INPUT_RECORD rc;
DWORD dw;
COORD pos={0,0};
KEY_EVENT_RECORD keyEvent;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
while(1){
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &rc, 1, &dw); //핸들정보
keyEvent=rc.Event.KeyEvent;
printf("Key event: ");
if(keyEvent.bKeyDown){
if(keyEvent.wVirtualKeyCode==VK_ESCAPE) break;
else printf("%c\n",keyEvent.wVirtualKeyCode);
printf("key pressed\n");
}
else printf("key released\n");
}
return 0;
}
[결과]
[소스2]
#include
#include
#include
#include
int main(int argc, char *argv[]){
char ch;
while(1){
if(kbhit()){
ch=getch();
printf("%c\n",ch);
}
}
return 0;
}
[결과]
Key Event에 대해 간단히 두가지 형태로 살펴 보았습니다. 첫번째의 경우는 코딩 표현을 할 때 위와 같은 식으로만 표현하면 안됩니다. 키보드인지 마우스인지를 선택문(switch)을 통해 구분이저야 합니다. 저상태에서는 마우스를 콘솔창에 위치하면 마우스도 콘솔창 입력임으로 연속으로 Key Event처리 동작을 수행합니다. 이 문제만 있는 것이 아니라 딜레이시간이 없기 때문에 연속 키 눌림현상도 처리해야 합니다. 좀 디테일적으로 코딩 표현을 해야 합니다. 그런 문제때문에 두번째 소스처럼 간단한 표현으로 접근하여 사용합니다.