WM_CHAR 메세지를 이용하면 입력을 받을 수 있다는것을 알게 되었는데
한가지 문제가 있었다. 문자 이외에는 입력을 받지 않는다는 것이다.
그래서 ins,del키 기능키 는 문자키가 아니기 때문에 이런 키는 아무리 눌러봤자 WM_CHAR메세지에 전달이 안된다.
이럴 때는 WM_KEYDOWN을 사용한다. 단(ALT,한영키, 등 몇가지는 제외가 된다)
wParam에 전달되는 것은 문자 코드가 아니라 가상의 키코드가 간다 이 키도는 다음과 같이 정의 되어있다.
가상 키코드 | 값 | 키 |
VK_LBUTTON | 01 | |
VK_RBUTTON | 02 | |
VK_CANCEL | 03 | ctrl-break |
VK_MBUTTON | 04 | |
VK_BACK | 08 | backspace |
VK_TAB | 09 | tab |
VK_CLEAR | 0C | numlook이 꺼져 있을때 5 |
VK_RETRUN | 0D | entwer |
VK_SHIFT | 10 | shift |
VK_CONTROL | 11 | ctrl |
VK_MENU | 12 | alt |
VK_PAUSE | 13 | pause |
VK_CAPITAL | 14 | caps lock |
VK_ESCAPE | 1B | esc |
VK_SPACE | 20 | space |
VK_PRIOR | 21 | pgup |
VK_NEXT | 22 | pgdn |
VK_END | 23 | end |
VK_HOME | 24 | home |
VK_LEFT | 25 | 좌 화살표 |
VK_UP | 26 | 상 화살표 |
VK_RIGHT | 27 | 우 화살표 |
VK_DOWN | 28 | 하 화살표 |
VK_SELECT | 29 | |
VK_PRINT | 2A | |
VK_EXECUTE | 2B | |
VK_SNAPSHOT | 2C | print screen |
VK_INSERT | 2D | insert |
VK_DELETE | 2E | delete |
VK_HLEP | 2F 30~39 41~5A |
숫자키 0~9 영문자 A~Z |
VK_LWIN | 5B | 왼쪽 윈도우 키 |
VK_RWIN | 5C | 오른쪽 윈도우키 |
VK_APP | 5D | Application 키 |
VK_NUMPAD0~9 | 60~69 | 숫자패드 0~9 |
VK_MULTIPLY | 6A | 숫자패드의 * |
VK_ADD | 6B | 숫자패드의 + |
VK_SEPARATOR | 6C | |
VK_SUBTRACT | 6D | 숫자패드의 - |
VK_DECLMAL | 6E | 숫자패드의 . |
VK_DIVIDE | 6F | 숫자패드의 / |
VK_F1~F24 | 70~87 | F1~F24키 |
VK_NUMLOOK | 90 | NUMLOOK키 |
VK_SCROOL | 91 | SCROLL LOCK |
설마 이 표를 다 외울 생각을 하는 사람이 있는가? .. 있다면 할 필요 없다.
단순히 이런게 있다고만 기억하면 된다.
가상키는 현재는 물론 향후 나올지도 모르는 키에 대해서도 미리 정해두었다.
WM_KEYDOWN 메세지 처리 루틴에서 wParam의 값과 가상 키코드값을 비교해 봄으로서 어떤 키가 눌렀는지 알아낼 수 있다.
그럼 예제를 한번보도록 하자.
#include <windows.h>
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE nsakura;
LPCTSTR windName=TEXT("GFP KeyDown");
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){
HWND hWnd;
MSG Message;
WNDCLASS WndClass;
nsakura=hInstance;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=WndProc;
WndClass.lpszClassName=windName;
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW|CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow(windName,windName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,(HMENU)NULL,hInstance,NULL);
ShowWindow(hWnd,nShowCmd);
while(GetMessage(&Message,NULL,0,0)){
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return (int)Message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam){
HDC hdc;
PAINTSTRUCT ps;
static xpos=400;
static ypos=400;
switch(iMessage){
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
hdc=BeginPaint(hWnd,&ps);
TextOut(hdc,xpos,ypos,TEXT("GFP"),3);
EndPaint(hWnd,&ps);
return 0;
case WM_KEYDOWN:
switch(wParam){
case VK_UP:
ypos-=8;
break;
case VK_DOWN:
ypos+=8;
break;
case VK_RIGHT:
xpos+=8;
break;
case VK_LEFT:
xpos-=8;
break;
}
InvalidateRect(hWnd,NULL,true);
}
return (DefWindowProc(hWnd,iMessage,wParam,lParam));
}
키보드의 방향키를 누르면 gfp 글씨가 움직일 것이다.
InvalidateRect(hWnd,NULL,true); 이것을 false로 바꿔서 해보자
이런식으로 이동시키게 되면 잔상이 남게 될것이다. 뭐 이건 어제 설명했으니 자세한 설명은 패스하도록 하겠습니다.
자 위의 코드를 보고 스페이스바가 누르면 GFP글씨가 껌뻑이게 만들어보자.
방법은 자유.
본인이 사용한 방법은
TranslateMessage
그것을 아는가 키보드로부터 입력을 받으면 WM_KEYDOWN ->WM_CHAR->WM_KEYUP 순으로 메세지가 발생한다.
WM_KEYDOWN이 발생되면 내부적으로 그게 문자이면 WM_CHAR를 발생시키고 문자가 아닌경우 아무 일도 안하고
GetMeesage는 메세지큐에서 메세지를 꺼내고 TranslateMessage함수는 오로지 키보드로부터 문자키 입력 메세지인 WM_CHAR를
만들어내기 위한 것이다.
이 외에도 키보드 메세지들은
WM_SYSKEYDOWN,WM_SYSKEYUP, WM_SYSCHAR이 있는데
SYS(system)가 붙은건. ALT가키와 함께 눌러지는 키보드 메세지들이다.
단 리턴을 할때는 DefWindowProc으로 보내줘야한다. 그렇지 않으면 alt esc,alt tap등의 화면전환 키까지 불능이 되버리기 때문이다.
'Computer > Win API' 카테고리의 다른 글
WinApi 타이머 (0) | 2010.07.18 |
---|---|
WinApi 마우스 입력. (0) | 2010.07.18 |
WinApi input WM_CHAR (0) | 2010.07.17 |
WinApi MessageBox (0) | 2010.07.17 |
WinApi 여러가지 출력 (0) | 2010.07.16 |