버튼 추가하기: 컨트롤의 시작

버튼 입력창으로 프로그램 형태 갖추기

버튼 입력창을 추가하면, 단순한 그래픽 프로그램에서 실제로 사용자와 상호작용하는 애플리케이션으로 확장됩니다. 핵심은 컨트롤을 생성하고, WM_COMMAND 메시지로 이벤트를 처리하는 구조입니다.
이전 단계에서 GDI로 도형을 그렸다면, 이제는 사용자가 직접 입력하고 결과를 확인하는 흐름까지 이어지게 됩니다.

GDI 다음에 컨트롤을 배우는 이유

WinAPI에서 화면을 구성하는 방식은 두 가지로 나뉩니다.

구분 특징
GDI 직접 그리기, 자유도 높음
컨트롤 미리 만들어진 UI, 사용 간편

그래픽 출력 중심에서 사용자 인터페이스 구성 중심으로 넘어가는 단계입니다. 컨트롤을 활용하면 빠르게 프로그램 형태를 갖출 수 있습니다.

버튼 추가하기: BUTTON 클래스로 클릭 가능한 요소 만들기

버튼은 “BUTTON” 클래스를 사용하여 생성합니다.

#define ID_BUTTON 1

HWND hButton = CreateWindow(
    L"BUTTON",
    L"확인",
    WS_VISIBLE | WS_CHILD,
    50, 50, 100, 30,
    hwnd,
    (HMENU)ID_BUTTON,
    hInstance,
    NULL
);

컨트롤 ID는 매크로로 정의해두는 것이 좋습니다. 버튼에서 발생한 이벤트는 부모 윈도우로 전달되기 때문에, WndProc에서 처리해야 합니다.

입력창 추가하기: EDIT 클래스로 텍스트 입력 받기

입력창은 “EDIT” 클래스를 사용합니다.

#define ID_EDIT 2

HWND hEdit = CreateWindow(
    L"EDIT",
    L"",
    WS_VISIBLE | WS_CHILD | WS_BORDER,
    50, 100, 200, 25,
    hwnd,
    (HMENU)ID_EDIT,
    hInstance,
    NULL
);

입력창은 반드시 핸들을 저장해두어야 합니다. 이후 입력값을 읽을 때 이 핸들을 사용합니다.

버튼 클릭으로 입력값 읽기

컨트롤 이벤트는 모두 WM_COMMAND 메시지를 통해 부모 윈도우로 전달됩니다.

case WM_COMMAND:
{
    if (LOWORD(wParam) == ID_BUTTON && HIWORD(wParam) == BN_CLICKED)
    {
        wchar_t buffer[100];
        GetWindowText(hEdit, buffer, 100);

        MessageBox(hwnd, buffer, L"입력값", MB_OK);
    }
}
return 0;

핵심 구조는 다음과 같습니다.

  • LOWORD(wParam): 어떤 컨트롤인지 구분
  • HIWORD(wParam): 어떤 이벤트인지 구분

이 흐름을 통해 버튼 클릭 → 입력값 읽기 → 결과 출력까지 연결됩니다.
입력값이 비어 있는 경우는 대부분 입력창 핸들이 올바르게 전달되지 않았거나, 잘못된 변수를 사용한 경우입니다.
이 단계까지 오면 WinAPI에서 기본적인 사용자 인터페이스를 갖춘 프로그램 구조를 완성하게 됩니다.