본문 바로가기

Win32 API

4. Win32 API - Message


1. Message란?

message queue

  • Message는 Win32API에서 프로그램 간 통신을 담당하는 기본 단위로, 이벤트 및 작업에 대한 정보를 전달합니다.
  • 보통 프로그램에서 변화가 생겼을 때 Windows가 프로그램에게 알려주는 정보입니다.
  • 이러한 Message는 메시지 큐를 통해 전송됩니다.

Message 처리 예시


사용 예시

  • Message를 처리하는 부분.
int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
    , _In_ LPSTR lpszCmdParam, _In_ int nCmdShow)
{
     // ... 생략

while (GetMessage(&Message, 0, 0, 0)) {
        TranslateMessage(&Message);
        DispatchMessage(&Message);
    }

    // ... 생략
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
    switch (iMessage) {
        case WM_LBUTTONDOWN:
    {
        HDC hdc = GetDC(hWnd); // DC 얻기
        SetMapMode(hdc, MM_LOMETRIC); // 0.1mm 단위로 맵핑 모드 변경

        RECT r;
        GetClientRect(hWnd, &r); // 클라이언트 영역의 좌표를 얻는다.

        // SetViewportOrgEx(hdc, r.right / 2, r.bottom / 2, NULL);
        SetWindowOrgEx(hdc, 100, -50, NULL);

        // 중심이 (0, 0)이고 반지름이 2cm인 원을 그린다.
        Ellipse(hdc, 200, -200, 300, -300);

        ReleaseDC(hWnd, hdc); // DC 반납
        return 0;
    }
        // ... 생략.
    }
    // ...생략
}
  • LButton 클릭 후 처리 결과

LButton 클릭 후 원 생성


내용 설명

1. 사용자가 프로그램의 Winodw에서 LButton을 클릭합니다.

2. 시스템은 해당 이벤트를 감지합니다.

3. 이벤트를 Message로 변환합니다.

4. 시스템이 Message Queue에 Message를 등록합니다.

5. Window Procedure에서 WM_LBUTTONDOWN Message를 감지하고 이에 대한 처리를 수행합니다. 특정 동작이나 함수 호출이 발생할 수 있습니다. 위의 예시에서는 WndProc 함수에서 이를 처리합니다.


2. Message Loop

Windows 프로그램에서 Message를 처리하는 부분을 Message Loop라고 지칭합니다.

while(GetMessage(&Message,0,0,0)) {
    TranslateMessage(&Message);
    DispatchMessage(&Message);
}


GetMessage

함수 원형

BOOL GetMessage(
  [out]          LPMSG lpMsg,
  [in, optional] HWND  hWnd,
  [in]           UINT  wMsgFilterMin,
  [in]           UINT  wMsgFilterMax
);

System이 유지하는 Message Queue에서 Messag를 읽어들입니다. Message는 첫번째 인자가 지정하는 MSG 구조체에 저장됩니다.

함수는 읽어들인 Message가 프로그램을 종료하는 WM_QUIT일경우 False를 return하고, 그 외의 경우는 모두 True를 return합니다.

즉 Message Loop는 WM_QUIT Message가 읽혀질 때(프로그램이 종료될 때)까지 전체 while Loop가 실행됩니다.


TranslateMessage

함수 원형

BOOL TranslateMessage(
  [in] const MSG *lpMsg
);

키보드의 입력 Message를 가공하여 프로그램에서 쉽게 사용할 수 있도록 도와줍니다.

Windows는 키보드의 어떤 키가 눌러졌다거나 떨어졌을 때 키보드의 Message를 발생시킵니다.

해당 함수는 키보드의 눌림(WM_KEYDOWN)과 떨어짐(WM_KEYUP)이 연속적으로 발생할 때 문자가 입력되었다는 메시지(WM_CHAR)를 만드는 역할을 수행합니다.


DispatchMessage

함수 원형

LRESULT DispatchMessage(
  [in] const MSG *lpMsg
);

System의 MessageQueue에서 꺼낸 Message를 프로그램의 Message 처리 함수인 (WndProc)로 전달합니다.

해당 함수를 사용하여 Message가 프로그램으로 전달되며 프로그램에서는 전달된 Message를 점검하여 다음 동작을 결정합니다.

Message Loop의 작업은 Message Queue에서 Message를 꺼낸 뒤 Message 처리 함수로 보내주는 역할입니다.


3. WndProc 함수

WndProc 함수 원형

WNDPROC Wndproc;

LRESULT Wndproc(
  HWND unnamedParam1,
  UINT unnamedParam2,
  WPARAM unnamedParam3,
  LPARAM unnamedParam4
)
{...}


WndProc란?

  • Window Procedure 함수로 메시지를 사용자 정의할 수 있는 함수입니다.
  • hWnd : Window에 대한 Handle 값입니다.
  • uMsg : System의 Message Queue로부터 전달받은 Message code 값입니다.
  • wParam | lParam : Message에 대한 추가적인 데이터를 포함하고 각 Message 코드마다 의미를 다르게 해석합니다.


WndProc의 처리 구조 일반 예시

switch(iMessage)
{
    case Msg1:
        // process1
        return 0;
    case Msg2:
        // process2
        return 0;
    case Msg3:
        // process3
        return 0;
    default:
        return DefWindowProc(...);
}


참조

MessageLoop - soen
WndProc - soen

'Win32 API' 카테고리의 다른 글

6. Win32 API - WindowClass  (0) 2024.02.24
5. Win32 API - Event  (0) 2024.02.24
3. Win32 API - hInstance  (0) 2024.02.19
2. Win32 API - Handle  (0) 2024.02.19
1. Win32 API - 코딩 규칙  (0) 2024.02.19