WWolves Den

DirectX 11 · 약 4분

WinMain과 창 핸들: Windows 프로그램의 시작점 읽기

HINSTANCE를 프로세스 ID와 혼동하지 않고, 창 클래스 등록부터 HWND 생성까지의 역할을 정리합니다.

Wolfgadeok · 업데이트

진입 함수가 받는 네 가지 정보

Windows GUI용 C++ 프로젝트에서 사용하는 wWinMain은 애플리케이션의 시작 함수를 나타냅니다. 일반적인 구성에서는 런타임 초기화 코드가 준비 작업을 한 뒤 이 함수를 호출합니다. 따라서 이를 단순히 실행 파일의 맨 첫 기계어 주소와 동일시하거나, 링크 오류를 피하려고 함수 이름만 바꾸는 설명은 충분하지 않습니다.

hInstance는 실행 모듈을 식별하는 핸들이며 프로세스 ID가 아닙니다. hPrevInstance도 이전 프로세스의 ID가 아니고 현대 Win32 환경에서는 사용하지 않는 매개변수입니다. pCmdLine은 프로그램 이름을 제외한 명령행 인수를, nCmdShow는 초기 표시 상태에 관한 정보를 전달합니다. 진입 함수의 각 인수가 무엇을 나타내는지 구분하면 이후 창을 등록하고 표시하는 코드의 역할을 이해하기 쉽습니다.

예제 · cpp

#include <Windows.h>

int WINAPI wWinMain(HINSTANCE instance,
                    HINSTANCE previousInstance,
                    PWSTR commandLine,
                    int showCommand)
{
    UNREFERENCED_PARAMETER(previousInstance);
    UNREFERENCED_PARAMETER(commandLine);
    // instance로 창 클래스를 등록하고 창을 생성합니다.
    // 생성 성공 후 ShowWindow(hwnd, showCommand)를 호출합니다.
    return 0;
}

창 클래스와 실제 창은 다르다

WNDCLASS 또는 WNDCLASSEX에는 창의 동작을 처리할 콜백, 커서, 아이콘, 클래스 이름 등을 지정합니다. RegisterClass 계열 함수는 이를 운영체제에 등록하고, CreateWindowEx는 등록된 클래스를 사용하여 실제 창을 만듭니다. 생성 결과인 HWND가 그 창을 식별하는 핸들입니다. 동일한 창 클래스로 여러 창을 만들 수 있으므로 클래스 등록과 인스턴스 생성을 분리해 이해합니다.

CS_HREDRAW와 CS_VREDRAW는 크기가 변했을 때 다시 그릴 영역과 관련된 창 클래스 스타일이지, 그 자체로 크기 조절 테두리를 만드는 옵션이 아닙니다. 창의 크기 조절 가능 여부는 창 스타일 등 별도 설정과 관련됩니다. 함수가 반환하는 실패 값도 확인해야 하며, 등록이나 생성에 실패한 HWND를 곧바로 다른 API에 넘기지 않습니다.

핸들을 내부 주소 설명으로 대체하지 않기

입문자가 알아야 할 것은 각 핸들을 어느 API에 전달할 수 있고 언제까지 유효한지입니다. 운영체제의 내부 리스트나 메모리 배치를 추측하여 핸들을 직접 해석하려는 접근은 도움이 되지 않습니다. 같은 숫자처럼 보이더라도 HWND, HINSTANCE, 프로세스 ID는 서로 바꿔 쓰는 값이 아닙니다.

처음 실습에서는 창 만들기와 닫기만 확인합니다. 그 다음 메시지 루프를 붙이고, 그림을 그리는 작업은 별도 단계로 추가합니다. 창을 띄우는 단계에서 실패한 것인지 렌더러 생성에서 실패한 것인지 경계를 나누면 화면이 안 뜨는 문제를 훨씬 빠르게 좁힐 수 있습니다.

참고 자료

예제는 학습용이며, 모든 환경에서 실행 검증된 완성 프로젝트는 아닙니다. 적용 전 사용 중인 버전과 프로젝트 환경에서 동작을 확인하세요.