본문 바로가기
Win32 API/기초

Win32 API 기초 : Key Manager (2)

글: 시플마 2024. 7. 3.

키 입력을 받으면 사각형이 움직이게 코드를 작성하였습니다.

 

그런데 문제는 윈도우가 내려가 있거나 다른 윈도우를 포커싱하고 있는 등

우리 프로그램의 윈도우가 포커싱되지 않은 상태에서도 

키 입력이 들어오면 사각형이 움직입니다.

 

CKeyMgr 클래스를 통해 만든 키 매니저의

update 함수에서 GetAsyncKeyState 함수를 통해 

키 입력을 받았기 때문입니다.

 

다른 윈도우를 포커싱하고 있어도 프로그램이 돌아가고 

있기만 한다면 GetAsyncKeyState 함수는 비동기 함수이므로

키 입력이 작동하는 것이죠.

 

 

그래서 아래 코드처럼 

 

키 매니저의 update 함수를 수정해 주었습니다.

 

61번째 줄에서 GetMainHwnd 함수를 통해

메인 윈도우 핸들을 반환받아 hMainHwnd라는 지역 변수에

저장합니다. 

 

그리고 62번째 줄에서 현재 포커싱하고 있는 윈도우의 핸들을 반환하는

GetFocus 함수를 호출하여 hWnd라는 지역 변수에 저장하죠.

 

이렇게 해 놓으면 메인 윈도우 핸들을 저장한 hMainHwnd와 

현재 포커싱하고 있는 윈도우 핸들을 저장한 hWnd를 비교하여

같다면, 즉 메인 윈도우를 포커싱하고 있다면 동작하게 하고

다르다면, 즉 메인 윈도우를 포커싱하고 있지 않다면 동작하지 않게

하는 방식으로 코드를 작성할 수 있죠.

 

GetFocus 함수는 우리 프로그램의 윈도우 핸들을 

반환하는 함수로써 우리 프로그램 이외의 윈도우가

포커싱되어 있는 상태라면 NULL을 반환합니다.

 

일단 우리 프로그램의 윈도우를 포커싱하고 있다면

키 입력이 작동하게 할 것이기 때문에 61번째 줄을

주석 처리하고 GetFocus 함수의 반환값을 저장하고 있는

hWnd의 값이 NULL인지 아닌지만 확인하여

코드를 작성하겠습니다.

 

 

65번째 if 문은 hWnd의 값이 nullptr이 아니라면,

즉 우리 프로그램의 윈도우를 포커싱하고 있는

상태라면 키 입력에 대한 코드가 동작하도록 하고 있습니다.

 

 

CKeyMgr 클래스의 update 함수의 102번째 줄의 else 문은

 

hWnd의 값이 nullptr이면, 즉 어떤 윈도우도 포커싱하고 있지 않거나

우리 프로그램 이외의 윈도우를 포커싱하고 있는 상태라면

반복문을 통해 모든 키의 bPrevPush 값을 false로 합니다.

 

108번째 if 문은 특정 키가 TAP 또는 HOLD 상태라면

해당 키를 AWAY 상태로 바꿉니다.

 

NONE이 아닌 AWAY 상태로 바꾸는 이유는

만약 키를 쭉 눌렀다가 떼는 순간 이벤트가 발생하는

코드를 작성하였다고 가정해 봅시다.

 

대전 격투 게임이면 키를 눌러 기를 모았다가

떼는 순간 기술이 나가는 경우를 예로 들 수 있겠죠.

 

X 키를 눌러 기를 모으다가( HOLD 상태 )

다른 윈도우를 클릭해서 격투 게임의 윈도우에서 벗어났습니다.

 

격투 게임의 윈도우에서 벗어난 순간, 

키보드에서 손이 떼졌다고 판단해 기술이 나가야겠죠?

 

하지만 격투 게임의 윈도우에서 벗어난 순간,

X 키의 상탯값을 바로 NONE으로 하게 되면

기술이 나가지 않게 됩니다.

 

X 키가 눌렸다가 떼지는 경우, 즉 X 키가

AWAY 상태가 되면 기술이 나가게 구현되어

있을 것인데 X 키의 상탯값을 NONE으로 하면 

애초에 X 키가 눌린 적이 없던 것으로 되어

아무런 이벤트도 발생하지 않는 것이죠.

 

이러한 이유로 키가 눌린 상태인 

TAP과 HOLD 상태의 경우는

윈도우에서 벗어나면 AWAY 상태가 되도록

하는 겁니다.

 

 

만약 특정 키가 AWAY 상태라면, 

윈도우에서 벗어나는 순간 해당 키를

NONE 상태로 바꿉니다.

 

 

만약 특정 키가 이미 NONE 상태라면

그대로 두어도 상관없겠죠.

 

 

기존에는 윈도우가 내려가 있거나 다른 윈도우를

포커싱하고 있어도 키를 입력하면 사각형이 움직였는데

코드를 수정한 이후 프로그램을 실행해 보면

오직 우리 프로그램의 윈도우가 포커싱된 경우에만

키 입력을 인식하여 사각형이 움직이는 것을 확인할 수 있습니다.

 

 

 


강의 출처 : https://www.youtube.com/watch?v=sLjH4M28DUc


'Win32 API > 기초' 카테고리의 다른 글

Win32 API 기초 : Scene Manager (2)  (0) 2024.07.05
Win32 API 기초 : Scene Manager (1)  (0) 2024.07.04
Win32 API 기초 : Key Manager (1)  (0) 2024.07.01
Win32 API 기초 : Double Buffering  (0) 2024.06.30
Win32 API 기초 : Timer (2)  (0) 2024.06.29