출처: http://blog.naver.com/stweed?Redirect=Log&logNo=30013921792
etAsyncKeyState()함수 와 GetKeyState()함수는 키보드의 키가 눌렸는지를
체크하는 함수들이다.
GetAsyncKeyState() 함수는 비 동기(Asynchronism)로 처리한다.
즉, 호출된 시점에서 키 상태를 조사하여, 메시지 큐를 거치지 않고 바로 리턴을 해 주므로
키 입력을 바로 처리해 줄 수가 있다.
GetKeyState() 함수는 호출된 시점에서 메시지 큐를 거치며, 메시지 발생 후의 상태를
리턴하게 되므로, 키보드 메시지 처리 루틴내에서 사용해야 한다.
게임과 같이 키 입력에 바로 반응을 해 줘야 하는 프로그램에서는 GetAsyncKeyState()함수
를 사용하는 편이 좋다.
GetAsyncKeyState()함수의 사용은
if( GetAsyncKeyState(VK_RETURN) ) //enter 키가 눌렀다면
{ //처리 }
이렇게 직접 쓰여도 되지만, 아래와 같은 형식으로 많이 사용한다.
if( GetAsyncKeyState(VK_RETURN) & 0x8000 ) //enter 키가 눌렀다면
{ //처리 }
왜??? 0x8000 으로 AND 연산을 통하여 키눌림을 체크할까??
GetAsyncKeyState() 함수는, 키가 눌려진 시점에서 0x8000 값을 리턴해 준다.
그리고 함수가 호출되었을때 키가 눌려져 있었다고 0x0001 값을 리턴해 준다.
즉, 0x8000 은 현재 키가 눌려진 상태를 뜻하고, 0x0001은 지난번 호출과 이번 호출사이에
키가 눌려진 적이 있었다라는 것을 뜻한다.
예를 들어, 아래 방향키가 게임내에서 비행기도 움직이고, 메뉴에서 위아래 선택에도
쓰인다고 가정해 보자.
AND 연산없이 그냥 사용하여 비행기를 움직이다가, F1키를 눌러 메뉴를 띄웠을 때 커서가
자동으로 아래쪽으로 내려갈 위험성이 생긴다.
왜냐하면, F1키를 누르는 시점에서 - if( GetAsyncKeyState(VK_F1) ) - VK_DOWN 은
눌리지 않았지만 리턴값이 0x0001이 되어 if( GetAsyncKeyState(VK_F1) ) 전에 호출된
if( GetAsyncKeyState(VK_DOWN) )이 참이 되기 때문이다.
하지만, 0x8000으로 AND연산을 하면
1000 0000 0000 0000 (키눌림 0x8000) 0000 0000 0000 0001 (눌려진적이 있음 0x0001)
& 1000 0000 0000 0000 (AND 연산 0x8000) &1000 0000 0000 0000 (AND 연산 0x8000)
---------------------- ---------------------
1000 0000 0000 0000 (키눌림 0x8000) 0000 0000 0000 0000 (키 안 눌림)
위와 같은 결과가 되어, 정확한 시점에서 키가 눌려진 상태를 체크할 수가 있는 것이다.
즉, 정확한 시점에서 키눌림 상태를 체크하기 위해서 0x8000 으로 AND 연산을
해 주는 것이다.
GetKeyState() 함수의 사용 예:
------------------------------------------------------------------------------------------
//키보드 메시지 처리루틴이 있는 콜백함수 내에서...
//char szTemp[256];
case WM_KEYDOWN:
//Ctrl+ 왼쪽 화살표키가 눌렸는지 조사
if( (wParam==VK_LEFT) && (GetKeyState(VK_CONTROL)<0) )
{
wsprintf(szTemp,"Ctrl키와 왼쪽화살표키가 눌림");
}
return 0;
----------------------------------------------------------------------------
GetKeyState()함수의 리턴값이 음수일 경우는 해당키가 눌린 상태이고, 음수가 아닐 경우는
해당키가 눌리지 않은 상태이다.