창 만들기

창 클래스

창 클래스는 여러 창에 공통적으로 있을 수 있는 동작 집합을 정의합니다. 예를 들어 단추 그룹에서는 사용자가 단추를 클릭할 때 각 단추의 동작이 비슷합니다. 물론 단추가 완전히 동일하지는 않습니다. 각 단추는 자체 텍스트 문자열을 표시하고 자체 화면 좌표를 줍니다. 각 창에 대해 고유한 데이터를 인스턴스 데이터라고 합니다.

프로그램에서 해당 클래스의 인스턴스를 하나만 만드는 경우에도 모든 창은 창 클래스와 연결되어야 합니다. 창 클래스가 C++ 의미에서 "클래스"가 아니라는 것을 이해하는 것이 중요합니다. 오히려 운영 체제에서 내부적으로 사용하는 데이터 구조입니다. 창 클래스는 런타임에 시스템에 등록됩니다. 새 창 클래스를 등록하려면 먼저 WNDCLASS 구조를 입력합니다.

// Register the window class.
const wchar_t CLASS_NAME[]  = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc   = WindowProc;
wc.hInstance     = hInstance;
wc.lpszClassName = CLASS_NAME;

다음 구조체 멤버를 설정해야 합니다.

  • lpfnWndProc창 프로시저 또는 "window proc"라는 애플리케이션 정의 함수에 대한 포인터입니다. 창 프로시저는 창의 동작 대부분을 정의합니다. 창 절차는 나중에 자세히 살펴보겠습니다. 지금은 이것을 전방 참조로 처리합니다.
  • hInstance 는 애플리케이션 인스턴스에 대한 핸들입니다. wWinMainhInstance 매개 변수에서 이 값을 가져옵니다.
  • lpszClassName 은 창 클래스를 식별하는 문자열입니다.

클래스 이름은 현재 프로세스에 로컬이므로 프로세스 내에서만 고유해야 합니다. 그러나 표준 Windows 컨트롤에는 클래스도 있습니다. 이러한 컨트롤을 사용하는 경우 컨트롤 클래스 이름과 충돌하지 않는 클래스 이름을 선택해야 합니다. 예를 들어 단추 컨트롤의 창 클래스 이름은 "Button"입니다.

WNDCLASS 구조에는 여기에 표시되지 않는 다른 멤버가 있습니다. 이 예제와 같이 0으로 설정하거나 입력할 수 있습니다. WNDCLASS 설명서에서는 구조에 대해 자세히 설명합니다.

다음으로, WNDCLASS 구조체의 주소를 RegisterClass 함수에 전달합니다. 이 함수는 운영 체제에 창 클래스를 등록합니다.

RegisterClass(&wc);

창 만들기

창의 새 인스턴스를 만들려면 CreateWindowEx 함수를 호출합니다.

HWND hwnd = CreateWindowEx(
    0,                              // Optional window styles.
    CLASS_NAME,                     // Window class
    L"Learn to Program Windows",    // Window text
    WS_OVERLAPPEDWINDOW,            // Window style

    // Size and position
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

    NULL,       // Parent window    
    NULL,       // Menu
    hInstance,  // Instance handle
    NULL        // Additional application data
    );

if (hwnd == NULL)
{
    return 0;
}

CreateWindowEx 함수에 대한 설명서에서 자세한 매개 변수 설명을 읽을 수 있지만 요약은 다음과 같습니다.

  • 첫 번째 매개 변수를 사용하면 창에 대한 몇 가지 선택적 동작(예: 투명 창)을 지정할 수 있습니다. 기본 동작에 대해 이 매개 변수를 0으로 설정합니다.
  • CLASS_NAME 는 창 클래스의 이름입니다. 만드는 창의 유형을 정의합니다.
  • 창 텍스트는 다양한 유형의 창에서 다양한 방식으로 사용됩니다. 창에 제목 표시줄이 있으면 텍스트가 제목 표시줄에 표시됩니다.
  • 창 스타일은 창의 모양과 느낌을 정의하는 플래그 집합입니다. 상수 WS_OVERLAPPEDWINDOW 실제로 비트 OR과 결합된 여러 플래그입니다. 이러한 플래그를 함께 사용하면 창에 제목 표시줄, 테두리, 시스템 메뉴, 최소화최대화 단추가 표시됩니다. 이 플래그 집합은 최상위 애플리케이션 창에서 가장 일반적인 스타일입니다.
  • 위치 및 크기의 경우 상수 CW_USEDEFAULT 기본값을 사용하는 것을 의미합니다.
  • 다음 매개 변수는 새 창에 대한 부모 창 또는 소유자 창을 설정합니다. 자식 창을 만드는 경우 부모를 설정합니다. 최상위 창의 경우 NULL로 설정합니다.
  • 애플리케이션 창의 경우 다음 매개 변수는 창의 메뉴를 정의합니다. 이 예제에서는 메뉴를 사용하지 않으므로 값은 NULL입니다.
  • hInstance 는 앞에서 설명한 인스턴스 핸들입니다. ( WinMain: 애플리케이션 진입점 참조)
  • 마지막 매개 변수는 void*형식의 임의 데이터에 대한 포인터입니다. 이 값을 사용하여 창 프로시저에 데이터 구조를 전달할 수 있습니다. 애플리케이션 상태 관리 섹션에서 이 매개 변수를 사용할 수 있는 한 가지 방법을 보여 드리겠습니다.

CreateWindowEx 는 새 창에 대한 핸들을 반환하고, 함수가 실패하면 0을 반환합니다. 창을 표시하려면 창을 표시합니다. 즉, 창 핸들을 ShowWindow 함수에 전달합니다.

ShowWindow(hwnd, nCmdShow);

hwnd 매개 변수는 CreateWindowEx에서 반환된 창 핸들입니다. nCmdShow 매개 변수를 사용하여 창을 최소화하거나 최대화할 수 있습니다. 운영 체제는 wWinMain 함수를 통해 이 값을 프로그램에 전달합니다.

창을 만드는 전체 코드는 다음과 같습니다. 함수 WindowProc 의 정방향 선언에 불과합니다.

// Register the window class.
const wchar_t CLASS_NAME[]  = L"Sample Window Class";

WNDCLASS wc = { };

wc.lpfnWndProc   = WindowProc;
wc.hInstance     = hInstance;
wc.lpszClassName = CLASS_NAME;

RegisterClass(&wc);

// Create the window.

HWND hwnd = CreateWindowEx(
    0,                              // Optional window styles.
    CLASS_NAME,                     // Window class
    L"Learn to Program Windows",    // Window text
    WS_OVERLAPPEDWINDOW,            // Window style

    // Size and position
    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

    NULL,       // Parent window    
    NULL,       // Menu
    hInstance,  // Instance handle
    NULL        // Additional application data
    );

if (hwnd == NULL)
{
    return 0;
}

ShowWindow(hwnd, nCmdShow);

축하합니다. 창을 만들었습니다. 지금은 창에 콘텐츠가 없거나 사용자와 상호 작용하지 않습니다. 실제 GUI 애플리케이션에서 창은 사용자 및 운영 체제의 이벤트에 응답합니다. 다음 섹션에서는 창 메시지가 이러한 종류의 대화형 작업을 제공하는 방법을 설명합니다.

다음

창 메시지