다음을 통해 공유


창 프로시저 작성

DispatchMessage 함수는 메시지의 대상인 창의 창 프로시저를 호출합니다. 창 프로시저에는 다음 서명이 있습니다.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

다음과 같은 네 개의 매개 변수가 있습니다.

  • hwnd는 창에 대한 핸들입니다.
  • uMsg는 메시지 코드입니다. 예를 들어 WM_SIZE 메시지는 창의 크기가 조정되었음을 나타냅니다.
  • wParamlParam에는 메시지와 관련된 추가 데이터가 포함되어 있습니다. 정확한 의미는 메시지 코드에 따라 달라집니다.

LRESULT는 프로그램이 Windows로 반환하는 정수 값입니다. 특정 메시지에 대한 프로그램의 응답을 포함합니다. 이 값의 의미는 메시지 코드에 따라 다릅니다. CALLBACK은 함수에 대한 호출 규칙입니다.

일반적인 창 프로시저는 단순히 메시지 코드를 켜는 큰 switch 문입니다. 처리하려는 각 메시지에 대한 사례를 추가합니다.

switch (uMsg)
{
    case WM_SIZE: // Handle window resizing

    // etc
}

메시지에 대한 추가 데이터는 lParamwParam 매개 변수에 포함됩니다. 두 매개 변수 모두 포인터 너비의 크기(32비트 또는 64비트)를 나타내는 정수 값입니다. 각각의 의미는 메시지 코드(uMsg)에 따라 달라집니다. 각 메시지에 대해 메시지 코드를 조회하고 매개 변수를 올바른 데이터 형식으로 캐스팅해야 합니다. 일반적으로 데이터는 숫자 값 또는 구조체에 대한 포인터입니다. 일부 메시지에는 데이터가 없습니다.

예를 들어 WM_SIZE 메시지에 대한 설명서에는 다음이 명시되어 있습니다.

  • wParam은 창이 최소화, 최대화 또는 크기 조정되었는지를 나타내는 플래그입니다.
  • lParam은 창의 새 너비와 높이를 하나의 32비트 또는 64비트 숫자로 압축된 16비트 값으로 포함합니다. 이러한 값을 얻으려면 비트 이동을 수행해야 합니다. 다행히 헤더 파일 WinDef.h에는 이 작업을 수행하는 도우미 매크로가 포함되어 있습니다.

일반적인 창 프로시저는 수십 개의 메시지를 처리하므로 상당히 길어질 수 있습니다. 코드를 모듈 특성이 좀 더 강하게 만드는 한 가지 방법은 각 메시지를 처리하는 논리를 별도의 함수에 배치하는 것입니다. 창 프로시저에서 wParamlParam 매개 변수를 올바른 데이터 형식으로 캐스팅하고 해당 값을 함수에 전달합니다. 예를 들어 WM_SIZE 메시지를 처리하기 위해 창 프로시저는 다음과 같습니다.

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_SIZE:
        {
            int width = LOWORD(lParam);  // Macro to get the low-order word.
            int height = HIWORD(lParam); // Macro to get the high-order word.

            // Respond to the message:
            OnSize(hwnd, (UINT)wParam, width, height);
        }
        break;
    }
}

void OnSize(HWND hwnd, UINT flag, int width, int height)
{
    // Handle resizing
}

LOWORDHIWORD 매크로는 lParam에서 16비트 너비 및 높이 값을 가져옵니다. 창 프로시저는 너비와 높이를 추출한 다음 이러한 값을 함수에 OnSize 전달합니다.

기본 메시지 처리

창 프로시저에서 특정 메시지를 처리하지 않는 경우 메시지 매개 변수를 DefWindowProc 함수에 직접 전달합니다. 이 함수는 메시지 유형에 따라 달라지는 메시지에 대한 기본 작업을 수행합니다.

return DefWindowProc(hwnd, uMsg, wParam, lParam);

창 프로시저에서 병목 현상 방지

창 프로시저가 실행되는 동안 동일한 스레드에서 만든 창에 대한 다른 모든 메시지를 차단합니다. 따라서 창 프로시저 내에서는 긴 처리를 피합니다. 예를 들어 프로그램이 TCP 연결을 열고 서버가 응답할 때까지 무기한 대기한다고 가정합니다. 창 프로시저 내에서 이 작업을 수행하면 요청이 완료될 때까지 UI가 응답하지 않습니다. 이 시간 동안 창은 마우스 또는 키보드 입력을 처리하거나, 자체적으로 다시 그리거나, 닫을 수 없습니다.

대신 Windows에 기본 제공되는 멀티태스킹 기능 중 하나를 사용하여 작업을 다른 스레드로 이동해야 합니다.

  • 새 스레드를 만듭니다.
  • 스레드 풀을 사용합니다.
  • 비동기 I/O 호출을 사용합니다.
  • 비동기 프로시저 호출을 사용합니다.

다음

창 그리기