본문 바로가기
프로그래밍/MFC (C++)

MFC ] PeekMessage() / GetMessage()와의 차이

by eteo 2023. 11. 14.

 

 

PeekMessage()와 GetMessage() 함수는 Windows 시스템 메시지 큐에서 메시지를 가져오는 함수이며, 동일한 4개의 매개변수를 갖는다.

 

BOOL PeekMessage(
    LPMSG lpMsg,
    HWND hWnd,
    UINT wMsgFilterMin,
    UINT wMsgFilterMax,
    UINT wRemoveMsg
);

 

  • lpMsg: MSG 구조체에 대한 포인터로, 함수 호출 이후 메시지 정보가 채워진다.
  • hWnd: 메시지를 확인할 창 또는 윈도우 핸들. 일반적으로 nullptr로 설정하면 어떤 윈도우에서든 해당 메시지를 확인한다.
  • wMsgFilterMin: 확인할 메시지 범위의 최소 값으로 WinUser.h에 정의되어 있다.
  • wMsgFilterMax: 확인할 메시지 범위의 최대 값으로  WinUser.h에 정의되어 있다.
  • wRemoveMsg: 메시지를 확인한 후 메시지 큐에서 제거할지 여부를 나타낸다.
    • PM_NOREMOVE: 메시지를 큐에서 제거하지 않는다.
    • PM_REMOVE: 메시지를 큐에서 제거한다.
    • PM_NOYIELD: 메시지를 확인하고 다른 스레드에 CPU를 양보하지 않고 진행한다.
  • BOOL 리턴값 : 메시지 큐에서 메시지를 확인되면 해당 메시지를 lpMsg에 채우고 TRUE를 반환한다, 큐에서 메시지 확인에 실패하면 FALSE를 반환한다.

 

 

GetMessage()와 PeekMessage의 차이

 

GetMessage() 는 시스템 메시지 큐가 비어있는 경우 메시지가 들어올 때까지 무한 대기하지만, PeekMessage() 는 바로 리턴해 메시지를 처리하지 않는 시간에 다른작업을 처리하도록 할 수 있다.

 

일반적인 윈도우 프로그램이라면 메시지 루프에 GetMessage()를 사용하여 메시지 큐가 비어있는 동안 유휴상태에 들어가 다른 프로세스가 CPU자원을 사용할 수 있도록한다. 하지만 게임 프로그램 같은 경우 메시지가 발생하지 않더라도 렌더링 등의 작업을 계속 처리해줘야 하므로 애플리케이션의 CPU점유율이 높아질 것을 감안하고 메시지루프에 PeekMessage()를 사용하기도 한다.

 

 

 

PeekMessage()를 사용하는 메시지루프 예시

 

while(msg.message != WM_QUIT)
{
      if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
      {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
      }
      else
      {
			// background process
      }
}

 

 

 

참고할만한 글

HOWTO: How to Use PeekMessage() Correctly in Windows

https://jeffpar.github.io/kbarchive/kb/074/Q74042/

 

Q74042: HOWTO: How to Use PeekMessage() Correctly in Windows

An Archive of Early Microsoft KnowledgeBase Articles

jeffpar.github.io