강께르의 개발일지
[WinAPI] 게임에서의 메시지 처리 본문
1. 일반적인 프로그램과 게임 프로그램의 차이
- 프로그램은 사용자가 발생시키는 메시지를 이용해 그에 맞는 일을 처리하며 동작한다.
- 예를 들어, 키보드와 마우스와 같은 입력이 메시지로 전달되어 그 이벤트에 맞게 프로그래밍된 동작을 수행할 것이다.
- 만약 일반적인 프로그램이라면 위와 같은 메시지를 받을 때까지 대기할 것이다. 아무런 동작하지 않고 오로지 메시지가 새로 올 때까지 무한정 대기하는 상태가 될 것이다.
- 하지만 게임은 일반적인 프로그램과 달리 취급해야 한다.
- 일반적인 프로그램은 메시지가 올 때까지 그 어느 동작도 수행하지 않는다. 게임도 그와 똑같다면, 메시지가 올 때까지, 그 어떤 애니메이션을 동작하지 않고 게임이 멈춰있는 것처럼 보일 것이다.
- 그에 따라서 일반적인 프로그램과 다르게 게임은 메시지를 처리에 대해 다르게 다뤄야 한다는 것을 인지할 수 있을 것이다.
2. GetMessage 함수
- 일반적인 프로그램에서 메시지를 처리할 때 사용하는 함수로 GetMessage가 있다.
- GetMessage 함수의 특징으로 메시지 큐에 메시지가 올 때까지 무한정 대기하는 것이다. 메시지가 오지 않는다면 대기하는 시간으로 idle time이라고 이런 대기 시간에 CPU를 다른 프로그램에서 사용할 수 있도록 하는 목적으로 대기한다.
- 메시지 큐에 메시지가 들어올 때까지 대기하다가 WM_QUIT 메시지를 받는다면 0를 반환한다.
3. PeekMessage 함수
- 게임에서 메시지를 처리할 때 사용하는 함수로 PeekMessage가 있다. 우선 PeekMessage의 원형을 보도록 하자.
BOOL PeekMessage (
LPMSG lpMsg;
HWND hWnd;
UINT wMsgFilterMin;
UINT wMsgFilterMax;
UINT wRemoveMsg;
);
- lpMsg는 메시지를 받을 구조체를 의미한다.
- hWnd는 메시지를 받을 윈도우를 의미한다. 매개변수로 받은 윈도우와 그 자식 윈도우와 관련된 메시지만 보게 된다. 만약 NULL이면 현재 쓰레드를 호출한 윈도우와 관련된 메시지를 보게 된다.
- wMsgFilterMin은 조사할 메시지의 최소값을 의미한다.
- wMsgFilterMax는 조사할 메시지의 최대값을 의미한다. 만약 위의 매개변수와 함께 0으로 전달된다면 메시지의 범위를 지정하지 않고 모든 메시지를 조사한다.
- wRemoveMsg는 조사한 메시지를 처리할 방법을 지정하는 플래그의 조합이다.
플래그 | 설명 |
PM_NOREMOVE | 메시지를 읽은 후 큐에서 메시지를 제거하지 않는다. |
PM_REMOVE | 메시지를 읽은 후 큐에서 메시지를 제거한다. |
PM_NOYIELD | 다른 스레드로 제어를 양보하지 않는다. |
PM_QS_INPUT | 마우스나 키보드 등의 입력 메시지만 처리한다. |
PM_QS_POSTMESSAGE | 타이머나 핫키 메시지를 포함하여 붙여지는 메시지만 처리한다. |
PM_QS_PAINT | 그리기 메시지만 처리한다. |
PM_QS_SENDMESSAGE | 보내지는 메시지만 처리한다. |
- 메시지 큐에 메시지가 있으면 0이 아닌 값을 반환하고, 없으면 0을 반환한다.
- PeekMessage는 GetMessage와 다르게 반환하기 전에 큐에 메시지가 들어오기를 기다리지 않는다.
- 이러한 특징을 이용해 메시지가 없다면 즉시 반환을 받고 그와 다른 루프를 수행할 수 있도록 한다.
- 그리고 WM_PAINT 메시지는 큐에서 제거하지 않고 처리될 때까지 큐에 남아 있는다.
- PeekMessage를 사용해 idle time일 때, 렌더링을 해주는 식으로 사용하는 것이다.
- PeekMessage는 메시지 유무만을 검사하고 WM_QUIT에 대한 메시지를 검사하지 않기 때문에 메시지 루프를 구성할 때, 이에 대한 조건문을 따로 만들어 줘야 한다.
4. TranslateMessage와 DispatchMessage
- TranslateMessage 함수는 키보드로부터 전달되는 메시지에서 눌려진 키가 문자키인지 검사하고 맞을 경우 WM_CHAR 메시지를 만들어 메시지 큐에 붙이는 역할을 한다.
- 만약 문자 입력이 아닐 경우 아무 일도 하지 않으며 이 메시지는 DisPatchMessage 함수에 이용된다.
- 만약 이 함수가 없다면 윈도우 프로시저에 WM_CHAR 메시지는 전달되지 않을 것이다.
- 여기서 WM_CHAR는 입력된 문자 코드와 눌러진 키와 키보드 상태에 대한 여러 가지 정보를 갖는 메시지이다.
- DispatchMessage 함수는 메시지 큐에서 메시지를 꺼내 프로그램의 메시지 처리 함수인 WndProc에 전달한다.
- 그리하여 프로그램은 전달받은 이 메시지를 통해 WndProc에서 다음 동작을 결정한다.
출처 :
'프로그래밍 > WinAPI' 카테고리의 다른 글
[WinAPI] SetTimer와 KillTimer (0) | 2021.06.25 |
---|