textpub.neocities.org . [ список статей ]

Мой перевод англоязычной статьи «Creating a Window» с сайта компании Microsoft (ссылка на оригинал: новая, старая), автор статьи там не указан, дата публикации оригинала: 05.10.2010 г.

Создание окна в Windows

Классы окна

Класс окна определяет поведение окон одного и того же типа. Например, окна, представляющие кнопки, одинаково ведут себя в случае, когда пользователь нажимает мышкой на кнопку. Конечно, кнопки не полностью идентичны; к примеру, на каждой из кнопок отображается своя собственная текстовая строка и каждая кнопка имеет свои собственные координаты на экране. Данные, уникальные для каждого окна, называются данными экземпляра.

Каждое окно обязательно связано с классом окна, даже если наша программа создает лишь один экземпляр этого класса. Важно понимать, что класс окна не является «классом» в понятиях языка C++. Скорее, это структура данных, используемая внутри операционной системы. Классы окна регистрируются операционной системой после запуска программы. Чтобы зарегистрировать новый класс окна, нужно сначала создать и заполнить структуру WNDCLASS:

    // Регистрируем класс окна
    const wchar_t CLASS_NAME[]  = L"Класс простого окна";
    
    WNDCLASS wc = { };

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

Мы должны определить следующие переменные структуры:

Названия классов окна действуют только внутри текущего процесса, поэтому эти названия не должны повторяться только внутри текущего процесса. Однако, стандартные оконные элементы управления в Windows также привязаны к своим классам. Если мы используем любой из этих элементов управления, мы должны выбирать названия для своих классов окна так, чтобы они не совпали с названиями стандартных классов окна элементов управления. Например, класс окна кнопочного элемента управления называется «Button».

Кроме перечисленных, структура WNDCLASS имеет и другие переменные. Вы можете оставить их равными нулю, как показано в этом примере, либо присвоить им значения. Документация MSDN описывает эту структуру подробнее.

На следующем шаге передадим адрес структуры WNDCLASS функции RegisterClass. Эта функция регистрирует класс окна в операционной системе.

    RegisterClass(&wc);

Создание окна

Чтобы создать новый экземпляр окна, вызываем функцию CreateWindowEx:

    // Создаем окно

    HWND hwnd = CreateWindowEx(
        0,                             // Дополнительные стили окна
        CLASS_NAME,                    // Класс окна
        L"Программирование в Windows", // Текст заголовка окна
        WS_OVERLAPPEDWINDOW,           // Стиль окна
        
        // Размеры и позиция на экране
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,      // Окно-родитель
        NULL,      // Меню
        hInstance, // Дескриптор экземпляра приложения
        NULL       // Дополнительные данные приложения
        );

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

Подробное описание параметров этой функции можно найти в MSDN, но здесь дадим короткую выжимку:

Функция CreateWindowEx возвращает дескриптор созданного окна или ноль, если функция завершилась с ошибкой. Чтобы отобразить окно на экране, нужно передать дескриптор созданного окна функции ShowWindow:

    ShowWindow(hwnd, nCmdShow);

Параметр hwnd — дескриптор окна, возвращенный функцией CreateWindowEx. Параметр nCmdShow используется для передачи информации о том, свернутым или развернутым должно быть окно. Операционная система передает это значение программе через функцию wWinMain.

Вот полный код для создания окна (помним, что WindowProc здесь — пока что только название функции, ее реализация будет рассмотрена позже):

    // Регистрируем класс окна
    const wchar_t CLASS_NAME[]  = L"Класс простого окна";
    
    WNDCLASS wc = { };

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

    RegisterClass(&wc);

    // Создаем окно

    HWND hwnd = CreateWindowEx(
        0,                             // Дополнительные стили окна
        CLASS_NAME,                    // Класс окна
        L"Программирование в Windows", // Текст заголовка окна
        WS_OVERLAPPEDWINDOW,           // Стиль окна

        // Размеры и позиция на экране
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

        NULL,      // Окно-родитель
        NULL,      // Меню
        hInstance, // Дескриптор экземпляра приложения
        NULL       // Дополнительные данные приложения
        );

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

    ShowWindow(hwnd, nCmdShow);

Поздравляем, вы научились создавать окно! На данный момент наше окно пока не содержит никакой информации и не взаимодействует с пользователем. В работающем приложении с оконным интерфейсом окно должно реагировать на события, порождаемые действиями пользователя или операционной системой. Следующая статья описывает, как такое взаимодействие реализуется с помощью обмена сообщениями.

textpub.neocities.org . [ список статей ]