강께르의 개발일지

[WinAPI] 게임에서의 메시지 처리 본문

프로그래밍/WinAPI

[WinAPI] 게임에서의 메시지 처리

강께르 2021. 6. 27. 23:00

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에서 다음 동작을 결정한다.

 

 

출처 :

더보기

https://skmagic.tistory.com/282

 

API-게임 메시지 구조(GetMessage,PeekMessage)

1.GetMessage 와 PeekMessage의 차이 GetMessage 는 메시지가 없으면 메시지가 생길떄까지 기다린다. 하지만 게임에서는 역동적이어야 하기때문에 GetMessage를 사용하는것이 좋은선택은아니다. 사용자가

skmagic.tistory.com

https://microsoft.tistory.com/85

 

게임루프와 일반메시지루프

** 게임루프와 일반메시지루프 ** 게임은 일반 윈도우 어플리케이션과는 달리 별다른 메세지가 없어도 자기할일을 묵묵히(?)수행해야 하는 어플리케이션입니다. 덕분에 일반 어플리케이션과는

microsoft.tistory.com

http://soen.kr/lecture/win32api/lec4/lec4-1-4.htm

 

Win32 API 입문 강좌

키보드에서 A키를 눌렀다 뗐다고 해 보자. 이 때 발생하는 메시지는 순서대로 WM_KEYDOWN, WM_CHAR, WM_KEYUP 세가지이다. 이 중 WM_CHAR 메시지는 사용자에 의해 발생하는 메시지가 아니다. 키보드로부터

soen.kr

http://soen.kr/lecture/win32api/reference/Message/WM_CHAR.htm

 

Win32 API Reference

설명 키보드로부터 문자키가 입력되었을 때 이 메시지가 보내진다. 여기서 문자키는 화면으로 출력 가능한 문자인 알파벳, 숫자, 기호 등을 의미하며 커서 이동키나, PgUp, PgDn 등의 기능키들은

soen.kr

https://hellowoori.tistory.com/9

 

WinMain 함수와 WndProc 함수

📂 이전글 - 참고 사이트 - 핸들 (Handle) 💬 일반적인 WIN32 프로그램의 구조를 이해해야, D3D 프로그램을 잘 이해할 수 있음!!! 목차 1. WinMain 함수와 WndProc 함수 2. WinMain 함수 설명   2-1. 윈도우..

hellowoori.tistory.com

 

'프로그래밍 > WinAPI' 카테고리의 다른 글

[WinAPI] SetTimer와 KillTimer  (0) 2021.06.25