ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [WinAPI] GetMessage와 PeekMessage의 차이
    개발 공부/Windows 개발 2023. 2. 12. 18:43

     

     

    *공통점*

    GetMessagePeekMessage는 Windows API에서 사용하는 메시지 관리 함수이며,

    메시지 큐에 메시지가 있을 때, 메시지를 가져오는 함수이다.

     

    *차이점*

    GetMessage ;

     - 메시지 큐에 메시지가 없으면 메시지가 생길 때까지 대기한다.

       메시지 큐에서 메시지를 사용할 수 있을 때까지 프로그램이 차단된다. (=> Blocking)

     - WM_QUIT 메시지 (프로그램 종료 메시지)가 들어오면 0을 반환한다.

     

    PeekMessage :

     - 메시지 큐에 메시지가 없으면 대기하지 않고 제어 권한이 바로 반환된다. (=> Non-blocking)

     - 메시지가 없으면 0을 반환한다. 메시지가 있다면 0이 아닌 값을 반환한다.

     - 메시지 큐에서 메시지를 가져오면서 그 메시지를 삭제하지 않도록 하는 옵션이 있다. `PM_NOREMOVE`

       GetMessage와 동일하게 메시지 큐에서 메시지를 삭제시키려면 'PM_REMOVE' 옵션을 사용하면 된다.

     

     

    번외

     

    기본적으로 Visual Studio에서 프로젝트를 생성했을 때 메시지 처리 코드 :

     while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

     

     

    게임 엔진과 같이 윈도우 메시지 처리 외에 상시적으로 처리해야 할 작업이 있을 경우 :

     while (true)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;
    
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    
        //TODO : 상시적으로 처리할 작업 수행
    }

    위의 경우, 한번 while문을 순회할 때마다 하나의 메시지만 처리할 수 있지만,

     

     

     

    한번에 메시지 큐를 모두 처리하고 싶다면

     while (true)
    {
        while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
                break;
    
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    
        //TODO : 상시적으로 처리할 작업 수행
    }

    PeekMessage가 0을 반환할 때 까지 (=메시지 큐가 Empty 가 될 때까지) 반복하고 다음을 처리하면 된다.

    해당 방법은 상황에 따라 적용하면 될 것같다. 

    한번에 너무 많은 양의 윈도우 메시지가 들어온다면, 메시지를 처리하는 동안 상시적으로 처리해주던 작업이 그만큼 딜레이가 생길 것이기 때문에 독이 될 수 있다.

     

     

     

    *참고 링크*

    GetMessage :

    https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessage

    PeekMessage :

    https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-peekmessagea

    한번의 순회마다 메시지 큐 계속 비우기 :

    https://www.gamedev.net/forums/topic/296990-getmessage-vs-peekmessage/

    댓글

Designed by Tistory.