textpub.neocities.org . [ список статей ]
Мой перевод англоязычной статьи «Creating a Window» с сайта компании Microsoft (ссылка на оригинал: новая, старая), автор статьи там не указан, дата публикации оригинала: 05.10.2010 г.
Класс окна определяет поведение окон одного и того же типа. Например, окна, представляющие кнопки, одинаково ведут себя в случае, когда пользователь нажимает мышкой на кнопку. Конечно, кнопки не полностью идентичны; к примеру, на каждой из кнопок отображается своя собственная текстовая строка и каждая кнопка имеет свои собственные координаты на экране. Данные, уникальные для каждого окна, называются данными экземпляра.
Каждое окно обязательно связано с классом окна, даже если наша программа создает лишь один экземпляр этого класса. Важно понимать, что класс окна не является «классом» в понятиях языка 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);
Поздравляем, вы научились создавать окно! На данный момент наше окно пока не содержит никакой информации и не взаимодействует с пользователем. В работающем приложении с оконным интерфейсом окно должно реагировать на события, порождаемые действиями пользователя или операционной системой. Следующая статья описывает, как такое взаимодействие реализуется с помощью обмена сообщениями.