До этого мы рассматривали только одно окно. Прежде чем перейти к другим типам, разберём основные операции с окнами:
Манипуляции с окном.
-
Создание и уничтожение:
-
Назначение:
Создание - CreateWindowExW, CreateWindowExA, CreateWindowW, CreateWindowA;
Уничтожение - DestroyWindow.
-
Синтаксис, объяснение:
Функции CreateWindowExW, CreateWindowW и CreateWindowExA, CreateWindowA отличаются следующим. Приставка Ex указывает на расширенную версию функции, которая поддерживает дополнительные стили окна. Различие между A и W заключается в кодировке строковых параметров: версия A использует кодировку ASCII, а версия W - Unicode (UTF-16).
Выбор функции должен соответствовать кодировке зарегистрированного класса окна. Если класс был зарегистрирован с ASCII, используйте CreateWindowA или CreateWindowExA; для Unicode (UTF-16) - CreateWindowW или CreateWindowExW. Остальные параметры этих функций аналогичны рассмотренным ранее.DestroyWindow - уничтожает любое окно, достаточно передать hwnd.
-
-
Отображение и видимость:
-
Назначение:
Управление видимостью окон - ShowWindow, ShowWindowAsync, ShowOwnedPopups, ShowScrollBar.
Анимация и уведомления - AnimateWindow, FlashWindow, FlashWindowEx
Проверка состояния окон - IsWindowVisible, IsWindow, IsWindowUnicode
-
Синтаксис, объяснение:
Функции ShowWindow и ShowWindowAsync принимают два аргумента: первый - hwnd окна, второй - идентификатор (nCmdShow), определяющий режим отображения. Полный список режимов можно найти в таблице ниже.
Разница между функциями заключается в поведении: ShowWindowAsync не блокирует поток, из которого она вызвана, в то время как целевое окно обрабатывает команду.Функция ShowOwnedPopups показывает или скрывает все всплывающие окна, связанные с указанным окном. Она принимает два аргумента: первый - hwnd окна, второй - значение true (показать) или false (скрыть).
Функция ShowScrollBar управляет видимостью полосы прокрутки. Она принимает три аргумента: hwnd окна или элемента прокрутки, тип полосы (SB_BOTH - обе стандартные полосы, SB_CTL - элемент полосы прокрутки, SB_HORZ - горизонтальная полоса, SB_VERT - вертикальная полоса) и значение true/false для отображения или скрытия.
-
Функция AnimateWindow добавляет анимацию при изменении видимости окна. Она принимает три параметра: hwnd окна (поток должен владеть этим окном), длительность анимации в миллисекундах и флаги анимации. Важно: перед использованием функции для скрытого окна необходимо предварительно вызвать ShowWindow. Флаги анимации:
Cкрыть(AW_HIDE) или показать (AW_ACTIVATE)
Направление анимации: слева направо(AW_HOR_POSITIVE), справа налево(AW_HOR_NEGATIVE), сверху вниз(AW_VER_POSITIVE), снизу вверх(AW_VER_NEGATIVE)
Тип анимации: меняется прозрачность и окно становится невидимым(и наоборот)(AW_BLEND), окно плавно появляется с той стороны которую указали и движется в конечную сторону(если с лева на право анимация, то появление с лева и до конца)(AW_SLIDE), изображение окна с углов уменьшается и движется в центр пока не пропадёт и так же обратно увеличивается(с центра)(AW_CENTER).
Функция FlashWindow - вы видели, как иконка приложения мигает на панели задач? Эта функция позволяет однократно мигнуть иконкой. Первым аргументом принимает hwnd окна, вторым - значение true (мигнуть) или false (должен возвращать в исходное состояние, но на практике часто не дает ожидаемого эффекта).
-
Функция FlashWindowEx - это расширенная версия FlashWindow, которая позволяет гибко настроить мигание иконки на панели задач. Она принимает указатель на заполненную структуру FLASHWINFO, содержащую следующие поля:
typedef struct { UINT cbSize; // Размер структуры HWND hwnd; // Дескриптор окна DWORD dwFlags; // Флаги мигания UINT uCount; // Количество миганий DWORD dwTimeout; // Интервал между миганиями (мс) } FLASHWINFO, *PFLASHWINFO;В целом всё понятно(для cbSize указывается значение sizeof(FLASHWINFO), про флаги мигания:
флаг FLASHW_ALL значение 0x00000003 - Мигать заголовком и кнопкой на панели задач.
флаг FLASHW_CAPTION значение 0x00000001 - Мигать только заголовком окна.
флаг FLASHW_TRAY значение 0x00000002 - Мигать только кнопкой на панели задач.
флаг FLASHW_STOP значение 0 - Остановить мигание(да, надо изменить флаг и вызвать повторно FlashWindowEx).
флаг FLASHW_TIMER значение 0x00000004 - Мигать до явной остановки.
-
флаг FLASHW_TIMERNOFG значение 0x0000000C - Мигать пока окно не станет активным.
Код-пример:FLASHWINFO fwi; fwi.cbSize = sizeof(FLASHWINFO); fwi.hwnd = hMainWindow; //указываете свой hwnd fwi.dwFlags = FLASHW_ALL; // Мигать всем окном fwi.uCount = 5; // 5 миганий fwi.dwTimeout = 0; // Системная скорость FlashWindowEx(&fwi);
-
Функция IsWindowVisible принимает только hwnd окна и возвращает true, если:
Само окно имеет стиль WS_VISIBLE
Все родительские окна также имеют этот стиль
Корневое окно не скрыто с помощью ShowWindow
IsWindow - принимает hwnd и проверяет, не уничтожено ли окно с таким hwnd.
IsWindowUnicode - принимает hwnd и проверяет, было ли окно зарегистрировано с помощью RegisterClassW. Если да, функция возвращает true.
-
-
Позиция и размер:
-
Назначение:
Управление размерами, позицией и размещением среди других окон - MoveWindow, SetWindowPos, BeginDeferWindowPos, DeferWindowPos, EndDeferWindowPos
Информация о окне(стиль, размер и т.п.) - GetWindowRect, GetClientRect, AdjustWindowRect, AdjustWindowRectEx, GetWindowPlacement
Восстановление позиции - SetWindowPlacement.
-
Синтаксис, объяснение:
MoveWindow - изменяет положение и размеры окна. Принимает: hwnd окна, координату X (от левого края экрана), координату Y, ширину, высоту и параметр перерисовки (true/false).
-
SetWindowPos - аналогична MoveWindow, но с дополнительными возможностями управления Z-порядком окон. Параметры:
hwnd окна
HWND для Z-порядка (можно передать числовое значение)
X, Y, ширина, высота
-
флаги управления:
флаг HWND_TOP , число 0 - поместить на вверх всех окон
флаг HWND_BOTTOM число 1 - в конце всех окон.
флаг HWND_TOPMOST число -1 - поместить на вверх всех окон, которые не закреплены.
флаг HWND_NOTOPMOST число -2 - как HWND_TOPMOST только снимет закрепление окна.
Дальше аргумент как у MoveWindow , и в конце ещё один флаг, список:
SWP_NOSIZE (0x0001) - сохраняет текущий размер
SWP_NOMOVE (0x0002) - сохраняет текущую позицию
SWP_NOZORDER (0x0004) - сохраняет Z-порядок
SWP_NOREDRAW (0x0008) - отключает перерисовку
SWP_NOACTIVATE (0x0010) - не активирует окно
SWP_DRAWFRAME (0x0020) - перерисовывает рамку окна
SWP_FRAMECHANGED (0x0020) - принудительный пересчет неклиентской области
SWP_SHOWWINDOW (0x0040) - показывает окно
SWP_HIDEWINDOW (0x0080) - скрывает окно
SWP_NOCOPYBITS (0x0100) - полная перерисовка клиентской облас
SWP_NOOWNERZORDER (0x0200) - не меняет Z-порядок окон-владельцев
SWP_NOSENDCHANGING (0x0400) - предотвращает отправку WM_WINDOWPOSCHANGING
SWP_DEFERERASE (0x2000) - подавляет WM_SYNCPAINT
SWP_ASYNCWINDOWPOS (0x4000) - асинхронное выполнение
-
Отложенное выполнение операций с окнами. До этого мы рассматривали функции, которые выполняются немедленно. Теперь разберем механизм отложенного выполнения операций с окнами:
BeginDeferWindowPos - инициализирует процесс отложенного выполнения. Принимает количество операций. Возвращает HDWP (псевдоним HANDLE) - ссылку на внутреннюю структуру.
DeferWindowPos - добавляет операцию в очередь. Параметры:
1.Указатель на HDWP (результат предыдущей функции).
2.HWND окна.
3.Позиция в Z-порядке.
4.Координаты X, Y.
5.Ширина, высота.
6.Флаги (рассмотренные ранее).
Важно: каждый вызов DeferWindowPos возвращает новый HDWP, который должен заменить старый.EndDeferWindowPos - выполняет все накопленные операции. Принимает финальный HDWP.
-
GetWindowRect - получает координаты окна относительно экрана. Параметры: hwnd, указатель на RECT. Пример:
RECT rect; if (GetWindowRect(hWnd, &rect)) { // rect.left, rect.top - левый верхний угол на экране // rect.right, rect.bottom - правый нижний угол на экране int width = rect.right - rect.left; int height = rect.bottom - rect.top; } -
GetClientRect - получает размеры клиентской области. Параметры аналогичны GetWindowRect (left и top всегда 0). Пример:
RECT clientRect; if (GetClientRect(hWnd, &clientRect)) { // clientRect.left == 0, clientRect.top == 0 int clientWidth = clientRect.right; // Ширина клиентской области int clientHeight = clientRect.bottom; // Высота клиентской области } AdjustWindowRect - вычисляет размер окна для нужной клиентской области. Параметры: указатель на RECT, стиль окна, наличие меню.
AdjustWindowRectEx - то же, что AdjustWindowRect, но с учетом расширенных стилей.
-
GetWindowPlacement - получает состояние и позицию окна. Параметры: hwnd, указатель на WINDOWPLACEMENT (предварительно инициализировать полем length = sizeof(WINDOWPLACEMENT)). О Структуре:
typedef struct { UINT length; UINT flags; UINT showCmd; POINT ptMinPosition; POINT ptMaxPosition; RECT rcNormalPosition; } WINDOWPLACEMENT;length - размер структуры в байтах
-
flags - принимает три флага:
WPF_SETMINPOSITION (0x0001) - установка позиции свернутого окна.
WPF_RESTORETOMAXIMIZED (0x0002) - восстановление в развернутом состоянии.
WPF_ASYNCWINDOWPLACEMENT (0x0004) - асинхронное выполнение.
showCmd - текущее состояние окна. Значение такие же как и у второго аргумента функции ShowWindow.
ptMinPosition - координаты свернутого окна.
ptMaxPosition - координаты развернутого окна.
rcNormalPosition - положение и размер в нормальном состоянии.
SetWindowPlacement - устанавливает состояние и позицию окна. Параметры аналогичны GetWindowPlacement.
-
-
Стили и свойства:
-
Назначение:
Изменения параметров окна: SetWindowLongPtrW / SetWindowLongPtrA , GetWindowLongPtrW / GetWindowLongPtrA , SetWindowWord, GetWindowWord, SetWindowStyle, GetWindowStyle, SetWindowExtStyle, GetWindowExStyle, ChangeWindowMessageFilter, ChangeWindowMessageFilterEx.
-
Синтаксис, объяснение:
-
SetWindowLongPtrW / SetWindowLongPtrA - Позволяют изменить многие поля структуры класса( я про WNDCLASS / WNDCLASSEX и т.п.) , первым аргументом hwnd окна, вторым специальный ид, отображает что за поле менять:
флаг GWL_EXSTYLE значение -20 - Задает новый расширенный стиль окна.
флаг GWLP_HINSTANCE значение -6 - Задает новый дескриптор экземпляра приложения.
флаг GWLP_HWNDPARENT значение -8 - Задает нового владельца для окна верхнего уровня.
флаг GWLP_ID значение -12 - Задает новый идентификатор дочернего окна. Окно не может быть окном верхнего уровня.
флаг GWL_STYLE значение -16 - Задает новый стиль окна .
-
флаг GWLP_USERDATA значение -21 - задаёт новые пользовательские данные
Третий аргумент, само значение.
GetWindowLongPtrW / GetWindowLongPtrA - как Set вариант функции, только получаем значение, первый аргумент hwnd, второй что за поле(как в Set варианте), возвращает запрашиваемое значение в типе LONG_PTR
SetWindowWord - устаревшая функция, по поведению как SetWindowLongPtr
GetWindowWord - устаревшая функция, по поведению GetWindowLongPtr
SetWindowStyle - Вспомогательная функция для установки стиля окна. Первый аргумент hwnd окна, второй новый стиль окна.
GetWindowStyle - Получаем стиль окна . Первый аргумент hwnd окна. Возвращаемое значение тип LONG.
SetWindowExtStyle - Вспомогательная функция для установки расширенного стиля окна , как SetWindowStyle , только стиль указываем расширяемый.
GetWindowExStyle , как GetWindowStyle только стиль получаем расширяемый.
ChangeWindowMessageFilter - Позволяет заблокировать или разблокировать сообщение для всего процесса. первый аргумент, сообщение, второй аргумент разрешение: MSGFLT_ADD (разрешить) , MSGFLT_REMOVE (запретить).
-
ChangeWindowMessageFilterEx - расширенная версия ChangeWindowMessageFilter, первый аргументом принимает hwnd окна, вторым сообщением, а третьим - флаг:
флаг MSGFLT_ALLOW число 1 - разрешить сообщение
флаг MSGFLT_DISALLOW число 2 - запретить сообщение
флаг MSGFLT_RESET число 0 - сбросить фильтр к состоянию по умолчанию
и четвёртый аргумент, не обязательный к слову, поэтому может быть null , принимает указатель на структуру CHANGEFILTERSTRUCT, которая содержит более подробный результат о работе функции, первое её поле это размер, тут по классике указываем sizeof(CHANGEFILTERSTRUCT) , а второе поле это уже результат функции:
флаг MSGFLTINFO_NONE число 0 - изменения не повлияло на фильтр
флаг MSGFLTINFO_ALLOWED_HIGHER число 1 - сообщение уже разрешено на более высоком уровне
флаг MSGFLTINFO_ALREADYDISALLOWED_FORWND число 2 - сообщение уже запрещено для окна
флаг MSGFLTINFO_ALREADYALLOWED_FORWND число 3 - сообщение уже разрешено для окна
-
-
-
Текст и заголовок:
-
Назначение:
Взаимодействие с текстом окна(заголовком) и текстом элементов управления - SetWindowTextW / SetWindowTextA , GetWindowTextW / GetWindowTextA, GetWindowTextLengthW / GetWindowTextLengthA
Изменить отображение окна - SetWindowRgn, GetWindowRgn
-
Синтаксис, объяснение:
SetWindowTextW / SetWindowTextA - Устанавливает текст заголовка окна или текст элемента управления. Первый аргумент hwnd окна или элемента управления, вторым указатель на строку с нужной кодировкой. Возвращает TRUE в случае успеха.
GetWindowTextW / GetWindowTextA - Копирует текст заголовка окна или элемента управления в буфер. Первый аргумент hwnd окна или элемента управления, второй - указатель на строку символов в нужной кодировке, третий аргумент кол-во символов включая нулевой завершитель. Возвращает кол-во скопированных символов, если ошибка то 0.
GetWindowTextLengthW / GetWindowTextLengthA - Возвращает длину текста заголовка окна или элемента управления. Принимает лишь hwnd окна или элемента управления, возвращает кол-во символов без учёта нулевого завершителя, если текст отсутствует, то 0.
-
SetWindowRgn - просто меняет форму окна, точней обрезает по шаблону. Принимает первым аргументом hwnd окна, второй - экземпляр HRGN , которой содержит трафарет(он возвращается результатом при помощи других функций:
CreateRectRgn - Прямоугольный шаблон. Первый аргумент, икс, второй игрик, это левый верхний угол, второй аргумент и третий, такие же значения, только правого нижнего.
CreateRectRgnIndirect - как CreateRectRgn , только координаты задаются через структуру RECT и потом одним аргументом указываются через указатель.
CreateEllipticRgn - Круг-Эллиптический шаблон. аргументы такие же как и у CreateRectRgn.
CreateEllipticRgnIndirect - как CreateEllipticRgn , только принимается указатель на RECT.
CreateRoundRectRgn - Прямоугольник со скругленными углами. как CreateRectRgn , только в конце ещё два аргумента ширина эллипса для скругления по X и высота эллипса для скругления по Y.
-
CreatePolygonRgn - Многоугольный регион. Первый аргумент массив с экземплярами структуры POINT(первое поле тип LONG название X, второе поле такой же тип и название Y), второй аргумент количество элементом массива, последний, режим заполнения(Эти режимы определяют, какие области многоугольника считаются "внутренними" и подлежат заливке):
ALTERNATE - Из точки проводится луч в любом направлении, считается количество пересечений с границами многоугольника, если число пересечений нечетное - точка внутри, если четное - точка снаружи.
WINDING - Учитывается направление обхода точек многоугольника, каждому сегменту присваивается "вес": +1 для по часовой, -1 для против часовой, суммируются веса всех пересеченных сегментов, если сумма не равна нулю - точка внутри.
-
CombineRgn - комбинирование двух регионов, первый аргумент, экземпляр HRGN , туда поместится результат, второй аргумент HRGN первый исходный регион, третий аргумент HRGN второй исходный регион, четвёртый аргумент флаги объединения:
RGN_AND - получится область, которая является областью пересечения двух шаблонов(HRGN)
RGN_OR - получится смесь областей, которые присуще или первому шаблону или второму или сразу двум.
RGN_XOR - получится итоговый шаблон, результат - области, которые принадлежат либо одному шаблону, либо второму, но не их пересечению.
RGN_DIFF - итоговый шаблон, это из первой шаблона вырезали второй.
RGN_COPY - итоговый шаблон, это копия первого указанного, второй игнорируется.
-
GetWindowRgn - получение шаблона окна, первый HWND окна, второе это дескриптор региона, который будет заполнен копией региона окна(HRGN) , возвращает флаг:
NULLREGION - форма окна стандартная
SIMPLEREGION - простая форма(один прямоугольник)
COMPLEXREGION - сложный регион
ERROR - ошибка параметров.
-
-
Состояние и активация:
-
Назначение:
Действия с состоянием активации окна - EnableWindow, IsWindowEnabled, SetActiveWindow, GetActiveWindow, SetFocus, GetFocus.
Изменения отображения - BringWindowToTop, CloseWindow, OpenIcon
-
Синтаксис, объяснение:
EnableWindow - Включает или отключает взаимодействие с окном. Первый аргумент hwnd, второй true или false.
IsWindowEnabled - Возвращает состояние окна(включено или отключено), принимает лишь hwnd.
SetActiveWindow - активирует окно(когда кликаете по программе на панели задач, она передвигается на передний план, тут такой же механизм), принимает hwnd окна. И возвращает дескриптор активированного окна.
GetActiveWindow - Возвращает дескриптор активного окна текущего потока.
SetFocus - Устанавливает фокус ввода(с клавиатуры например) на указанное окно. Принимает hwnd окна, возвращает его же.
GetFocus - Возвращает окно(HWND) на котором фокус ввода.
BringWindowToTop - делает окно по верх всех остальных принимает HWND окна, возвращает true или false.
CloseWindow - сворачивает окно, принимает HWND окна, возвращает true или false.
OpenIcon - восстанавливает окно, принимает HWND окна, возвращает true или false.
-
-
Порядок окон и родительские отношения:
-
Назначение:
Операции с позицией окна - GetNextWindow, GetTopWindow, GetWindow
Манипуляция с поиском и отношением окон - SetParent, GetParent, GetAncestor, FindWindowW / FindWindowA, FindWindowExW / FindWindowExA.
-
Синтаксис, объяснение:
GetNextWindow - получение следующее или предыдущее окно в позиции окон. Принимает HWND окна и флаг: GW_HWNDNEXT (следующее окно в позиции окон), GW_HWNDPREV (предыдущее). Возвращает HWND.
GetTopWindow - Получает верхнее (самое видимое) дочернее окно. Принимает hwnd окна, возвращает HWND.
-
GetWindow - Получает окно, связанное с указанным окном определенным способом. Принимает HWND окна первым аргументом и флаг, вторым аргументом(возвращает HWND):
GW_HWNDFIRST - первое окно в позиции окон
GW_HWNDLAST - последнее окно в позиции окон
GW_HWNDNEXT - следующее окно в позиции окон
GW_HWNDPREV - предыдущее окно в позиции окон
GW_OWNER - окно-владелец
SetParent - изменяет родительское окно для указанного дочернего окна. Первый аргумент hwnd дочернего окна, второй hwnd родительского окна для смены, возвращает функция hwnd прошлого окна родителя.
GetParent - получает родительское окно для указанного дочернего. Принимает лишь hwnd дочернего окна. Возвращает hwnd родительского окна.
-
GetAncestor - Получает предка окна указанного типа. Принимает hwnd окна, и флаги(тип предка и возвращает его hwnd):
GA_PARENT - родитель
GA_ROOT - корневой владелец (самое верхнее окно в цепочке владения)
GA_ROOTOWNER - корневой родитель (самое верхнее окно в цепочке родительства)
FindWindowW / FindWindowA - находит окно по имени класса и/или заголовку. Принимает два аргумента, первый это название класса (указатель на массив символов), второе это название окна(такой же указатель). Первое или второй или оба могут быть NULL, результат hwnd окна или NULL.
FindWindowExW / FindWindowExA - ищет дочерние окна, первый аргумент hwnd окна, если null , ищет среди всех закреплённых окон. Второй аргумент hwnd дочернего окна, после которого нужно начать поиск, если null , перебирает все, и последние два аргумента как у FindWindowW / FindWindowA.
-
-
Прозрачность и слои:
-
Назначение:
Манипуляция с прозрачностью окна - SetLayeredWindowAttributes, GetLayeredWindowAttributes, UpdateLayeredWindow, UpdateLayeredWindowIndirect
-
Синтаксис, объяснение:
В первую очередь, что бы функции работали, стиль окна должен быть WS_EX_LAYERED.
SetLayeredWindowAttributes - устанавливает прозрачность окна и цвет прозрачности. Первый аргумент hwnd окна, второй - цвет прозрачности (структура COLORREF), третий - значение альфа-канала(прозрачность), четвёртый - флаг - LWA_COLORKEY (все пиксели цвета второго аргумента станут прозрачными) , LWA_ALPHA (Использовать значение третьего аргумента для прозрачности).
GetLayeredWindowAttributes - получает текущие параметры прозрачности окна. Первый аргумент hwnd окна, остальные, указатели на цвет-прозрачность(COLORREF), альфа-значения(прозрачность), и флага.
-
UpdateLayeredWindow - обновляет содержимое слоистого окна(стиль WS_EX_LAYERED) с поддержкой альфа-канала для каждого пикселя. Аргументы:
HWND окна
HDC назначения (может быть NULL) (об этом HDC подробней когда дойдём до графики)
указатель на структуру POINT, новая позиция окна.
указатель на структуру SIZE, новый размер окна
HDC источника
указатель на структуру POINT, откуда начинать копирование окна.
указатель на структуру COLORREF, цвет прозрачности
-
указатель на структуру BLENDFUNCTION , функция смешивания:
typedef struct _BLENDFUNCTION { BYTE BlendOp; // всегда AC_SRC_OVER BYTE BlendFlags; // всегда 0 BYTE SourceConstantAlpha; // альфа-значение (0-255) BYTE AlphaFormat; // формат альфа-канала } BLENDFUNCTION, *PBLENDFUNCTION;формат - 0 (без альфа-канала), AC_SRC_ALPHA (0x1, исходное изображение содержит альфа-канал).
-
флаг операции:
ULW_ALPHA - использовать альфа-смешивание
ULW_COLORKEY - использовать цветовой ключ
ULW_OPAQUE - непрозрачное окно
ULW_EX_NORESIZE - не изменять размер окна
UpdateLayeredWindowIndirect , расширенная версия, первый аргумент hwnd, второй указатель на структуру UPDATELAYEREDWINDOWINFO, где поля такие же, как описывал выше, только в конце ещё одно поле указатель на структуру RECT, которая содержит координаты на клиент-ской области которую необходимо перерисовать, может быть NULL.
-
-
Перерисовка:
Данный пункт будет рассматриваться когда дойдём до графики.
-
Меню и системные команды:
-
Назначение:
Манипуляция с системным меню(под заголовком) - GetSystemMenu, SetMenu , GetMenu , DrawMenuBar , HiliteMenuItem.
-
Синтаксис, объяснение:
GetSystemMenu - получает дескриптор системного меню окна (меню в заголовке окна). Принимает HWND дескриптор окна, второй аргумент - false(получить дескриптор для модификации) или true(восстановить стандартное меню). Возвращает HWND системного меню.
SetMenu - устанавливает новое меню для окна. Принимает первым аргументом HWND окна, вторым дескриптор нового меню. Возвращает true или false
GetMenu - получает дескриптор меню окна. Первый аргумент HWND окна. Возвращает HWND или NULL.
DrawMenuBar - принудительно перерисовывает строку меню окна. Принимает HWND окна. Возвращает true или false.
HiliteMenuItem - выделяет или снимает выделение с элемента меню в строке меню. Первый аргумент HWND окна, второй HWND меню, третий ID пункта меню или позиция, четвёртый - комбинация флагов: MF_BYCOMMAND(ид пункта является ид-ом пункта меню), MF_BYPOSITION(позиция элемента меню, является отсчитываемой от нуля), MF_HILITE(выделяет пункт меню, если флага нет, выделение убирается), MF_UNHILITE(убирает выделение пункта меню).
-
-
Таймеры:
-
Назначение:
-
Синтаксис, объяснение:
-
SetTimer - Создает таймер с указанным интервалом. Первый аргумент HWND окна, которое будет получать сообщения WM_TIMER(если, нет callback функции), второе уникальный ид таймера(не 0, пишем сами ид), третий аргумент - интервал между срабатываниями в миллисекундах , и последний callback функция, её синтаксис:
VOID CALLBACK TimerProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { if (idEvent == 1) { // Обработка таймера } }hWnd - дескриптор окна, может быть NULL, в uMsg всегда будет WM_TIMER, idEvent ид таймера(его указывали), dwTime - текущее системное время, выраженное в миллисекундах. Это время, которое прошло с момента загрузки системы.
KillTimer - уничтожение таймера, первый аргумент HWND тот что указали в таймере, дальше ид таймера. Возвращает true или false.
IsWindowHung - проверка не зависло ли окно, принимает HWND окна и возвращает true или false.
-
-
-
Свойства окон:
Свойства окон - это механизм для хранения произвольных данных, связанных с окном.
-
Назначение:
Удаления свойства - RemovePropW, RemovePropA
Перечисление свойств - EnumPropsExW, EnumPropsExA
-
Синтаксис, объяснение:
SetPropW, SetPropA - первый аргумент hwnd окна, второй указатель на строку(названия свойства), и значение , но тип там HANDLE(указатель на тип void)
GetPropW, GetPropA - получение свойства, первый аргумент hwnd окна, второй указатель на строку и возвращает значение(HANDLE)
RemovePropW, RemovePropA - принимает такие же аргументы как GetPropW, GetPropA , возвращает в итоге либо значение которое было у свойство, либо NULL.
-
EnumPropsExW, EnumPropsExA - первый аргумент hwnd, второй это указатель на callback-функцию, третий аргумент это дополнительный параметр. Callback-функция:
BOOL CALLBACK PropEnumProcEx( HWND hWnd, // дескриптор окна LPTSTR lpString, // строка, название свойство HANDLE hData, // значение свойства ULONG_PTR lParam // дополнительный параметр из EnumPropsEx ){ }
-
-
Desktop Window Manager (DWM):
DWM (Desktop Window Manager) - компонент Windows, отвечающий за композицию и визуальные эффекты окон. Начиная с Windows Vista, DWM дают визуальные эффекты: прозрачность, размытие, живые миниатюры и другие.
-
Назначение:
Проверка включён ли DWN - DwmIsCompositionEnabled
Включение эффекта "размытие за окном" - DwmEnableBlurBehindWindow
Получение значений атрибутов окна, связанных с DWM - DwmGetWindowAttribute
Установка DWN атрибутов окна - DwmSetWindowAttribute
расширяет рамку окна в клиентскую область, создавая эффект "стекла" (Aero Glass) - DwmExtendFrameIntoClientArea
-
Синтаксис, объяснение:
DwmIsCompositionEnabled - принимает указатель на bool переменную, в ней будет результат.
DwmEnableBlurBehindWindow - первый аргумент hwnd окна, второй аргумент указатель на структуру DWM_BLURBEHIND.
DwmSetWindowAttribute - первый аргумент hwnd окна, второй аргумент, идентификатор атрибута(их список), третий аргумент указатель на значение атрибута ,
DwmGetWindowAttribute - как DwmSetWindowAttribute, только получение
-
DwmExtendFrameIntoClientArea - первый аргумент hwnd окна, второй указатель на структуру
MARGINS, которая определяет отступы рамки:typedef struct _MARGINS { int cxLeftWidth; // левый отступ int cxRightWidth; // правый отступ int cyTopHeight; // верхний отступ int cyBottomHeight; // нижний отступ } MARGINS;
-
-
DPI и масштабирование:
-
Назначение:
DPI (Dots Per Inch) - это система масштабирования в Windows, которая обеспечивает корректное отображение интерфейса на экранах с высокой плотностью пикселей.
устанавливает уровень осведомленности процесса о DPI - SetProcessDpiAwareness
получает значение DPI для конкретного окна - GetDpiForWindow
корректирует размер окна с учетом DPI - AdjustWindowRectExForDpi
включает масштабирование неклиентской области окна - EnableNonClientDpiScaling
получает контекст осведомленности о DPI для окна - GetWindowDpiAwarenessContext
устанавливает контекст осведомленности о DPI для окна - SetWindowDpiAwarenessContext
-
Синтаксис, объяснение:
SetProcessDpiAwareness - принимает лишь один флаг из трёх: PROCESS_DPI_UNAWARE - процесс не осведомлен о DPI, PROCESS_SYSTEM_DPI_AWARE - процесс использует системный DPI, PROCESS_PER_MONITOR_DPI_AWARE - процесс обрабатывает DPI для каждого монитора.
GetDpiForWindow - принимает лишь hwnd окна.
AdjustWindowRectExForDpi - как AdjustWindowRectEx, только добавляется ещё один аргумент в конце - значение DPI для расчета.
EnableNonClientDpiScaling - принимает лишь hwnd окна
GetWindowDpiAwarenessContext - принимает лишь hwnd окна
SetWindowDpiAwarenessContext - принимает контекст DPI для установки, возвращает предыдущий контекст.
-
-
Перечисление окон:
-
Назначение:
Перечисление всех окон верхнего уровня на рабочем столе - EnumWindows
Перечисление всех дочерних окон указанного родительского окна - EnumChildWindows
Перечисление всех окон, принадлежащие указанному потоку - EnumThreadWindows
-
Синтаксис, объяснение:
-
EnumWindows - первый аргумент callback-функция, второй дополнительные параметры. Callback-функция:
BOOL CALLBACK EnumWindowsProc( HWND hwnd, // дескриптор текущего окна LPARAM lParam // пользовательские данные ){ } EnumChildWindows - как EnumWindows только первый аргумент, это hwnd родительского окна.
EnumThreadWindows - как EnumChildWindows , только первый аргумент это ид потока.
-
-
-
Потоки и процессы:
-
Назначение:
Возвращает ид потока(а за одно и процесса через аргумент), который создал окно - GetWindowThreadProcessId
Присоединение или отсоединение двух потоков - AttachThreadInput
Получение идентификатора текущего потока - GetCurrentThreadId
-
Синтаксис, объяснение:
GetWindowThreadProcessId - принимает hwnd окна первым аргументом, а вторым указатель на DWORD , в нём будет помещено значение которое обозначает ид процесса (не обязательный параметр), возвращает ид потока
AttachThreadInput - первый аргумент , ид потока к которому будет присоединение, второй - ид того что подсоединять будем, третий аргумент: true(подсоединить) , false(отсоединить).
GetCurrentThreadId - возвращает текущий ид потока
-
На этом по сути и все действия.
Виды окон.
Окна верхнего уровня (Top-level Windows) - это основное окно приложения, дескриптор которого возвращается функцией CreateWindow/CreateWindowEx. Такое окно не имеет родительского окна.
-
Дочерние окна. В предыдущих статьях часто упоминались понятия "родительское окно" и "дочернее окно". Дочернее окно - это элемент, который является прямой частью другого окна, например, кнопки, поля ввода и другие элементы управления. Особенности дочерних окон:
Не имеют стандартной рамки окна
Являются частью клиентской области родительского окна
Не могут выходить за пределы родительского окна
Обязательно должны иметь стиль WS_CHILD
В следующих разделах будут приведены примеры кода.
Родительское окно - это окно, к которому привязаны дочерние окна. Оно содержит и управляет дочерними элементами интерфейса, такими как кнопки, поля ввода и другие контролы.
-
Владеемые окна - это особый тип окон, которые похожи на дочерние, но имеют важные отличия:
Используются для диалоговых окон, окон сообщений, окон ошибок и т.п.
Имеют владельца (owner), но не имеют стиля WS_CHILD
Могут выходить за пределы клиентской области родительского окна
Всегда отображаются поверх своего владельца
Закрываются/минимизируются вместе с владельцем
Более подробно с кодо-примерами:
-
Как уже упоминалось, дочерние окна в основном представляют собой элементы интерфейса. Прежде чем переходить к примерам кода, нужно описать существующие классы окон. По сути, тип элемента определяется классом окна при его создании. Также существует возможность создания пользовательского класса, но это будет рассмотрено позже, так как графики ещё не касались.
-
Самое просто это обычная кнопка(класс L"BUTTON").

-
Чекбокс(класс L"BUTTON"):
-
Квадратный.

-
Круглый.

-
-
Поле для ввода(класс L"EDIT")

-
Список(класс L"LISTBOX")

-
Комбинированный список(класс L"COMBOBOX")

-
Полоса прокрутки(скролл-бар(ползунок))(класс L"SCROLLBAR")

-
Статический текст(класс L"STATIC")

-
Просто рамка(класс L"STATIC")

-
А так же расширенный текст редактор (Rich Edit Control)(класс L"RichEdit20W").

-
Трэкбар(ползунок 2.0)(класс для Unicode UTF-16 - L"msctls_trackbar32", для ASCII - "msctls_trackbar32")

-
Индикатор выполнения(прогресс бар)(класс для Unicode UTF-16 - L"msctls_progress32", для ASCII - "msctls_progress32")

-
Счётчик(класс L"EDIT")

-
Вкладки(класс для Unicode UTF-16 - L"SysTabControl32", для ASCII - "SysTabControl32")

-
Дерево(когда при установке выбираете путь через меню, это меню - дерево)(класс для Unicode UTF-16 - L"SysTreeView32", для ASCII - "SysTreeView32")

-
Список с колонками(как в ворде таблица)(класс для Unicode UTF-16 - L"SysListView32", для ASCII - "SysListView32")

-
Заголовок(шапка таблица)(класс для Unicode UTF-16 - L"SysHeader32", для ASCII - "SysHeader32")

-
Поле для ввода горячих клавиш(класс для Unicode UTF-16 - L"msctls_hotkey32", для ASCII - "msctls_hotkey32")

-
Анимация(класс для Unicode UTF-16 - L"msctls_hotkey32", для ASCII - "msctls_hotkey32")

-
Выбор даты и времени(класс для Unicode UTF-16 - L"SysDateTimePick32", для ASCII - "SysDateTimePick32")

-
Календарь(класс для Unicode UTF-16 - L"SysMonthCal32", для ASCII - "SysMonthCal32")

-
Панель инструментов(класс для Unicode UTF-16 - L"ToolbarWindow32", для ASCII - "ToolbarWindow32")

После рассмотрения классов окон следует понимать, что дочерние окна создаются с помощью функции CreateWindowExW (или CreateWindowExA). Параметры функции:
Первый аргумент (расширенный стиль) обычно устанавливается в 0L
Второй аргумент - класс окна из рассмотренных ранее
-
Третий аргумент - стили окна, где:
Обязательный стиль: WS_CHILD
Обычно объединяется с WS_VISIBLE (чтобы окно было видно сразу)
-
Добавляются специфические стили для конкретного элемента:
класс BUTTON - https://learn.microsoft.com/ru-ru/windows/win32/controls/button-styles.
класс EDIT - https://learn.microsoft.com/ru-ru/windows/win32/controls/edit-control-styles.
класс LISTBOX - https://learn.microsoft.com/en-us/windows/win32/controls/list-box-styles.
класс COMBOBOX - https://learn.microsoft.com/en-us/windows/win32/controls/combo-box-styles.
класс SCROLLBAR https://learn.microsoft.com/en-us/windows/win32/controls/scroll-bar-control-styles.
класс STATIC https://learn.microsoft.com/en-us/windows/win32/controls/static-control-styles.
класс RichEdit20W - подходит https://learn.microsoft.com/en-us/windows/win32/controls/edit-control-styles.
класс TRACKBAR_CLASS - https://learn.microsoft.com/ru-ru/windows/win32/controls/trackbar-control-styles.
класс PROGRESS_CLASS - https://learn.microsoft.com/en-us/cpp/mfc/styles-for-the-progress-control?view=msvc-170.
класс WC_TABCONTROL - https://learn.microsoft.com/en-us/windows/win32/controls/tab-control-styles.
класс WC_TREEVIEW - https://learn.microsoft.com/en-us/windows/win32/controls/tree-view-control-window-styles.
класс WC_LISTVIEW - https://learn.microsoft.com/ru-ru/windows/win32/controls/extended-list-view-styles.
класс WC_HEADER - https://learn.microsoft.com/en-us/windows/win32/Controls/header-control-styles.
класс HOTKEY_CLASS - https://learn.microsoft.com/en-us/windows/win32/Controls/common-control-styles.
класс ANIMATION - https://learn.microsoft.com/en-us/windows/win32/controls/animation-control-styles.
класс DATETIMEPICK_CLASS - https://learn.microsoft.com/en-us/windows/win32/controls/date-and-time-picker-control-styles.
класс MONTHCAL_CLASS - https://learn.microsoft.com/en-us/windows/win32/controls/month-calendar-control-styles.
класс TOOLBAR - https://learn.microsoft.com/en-us/windows/win32/controls/toolbar-control-and-button-styles.
класс STATUSCLASSNAME - https://learn.microsoft.com/ru-ru/windows/win32/controls/status-bar-styles?source=recommendations.
Оставшиеся параметры CreateWindowEx для дочерних окон:
X, Y - позиция элемента(два отдельных аргумента)
Ширина, высота - размеры элемента(два отдельных аргумента)
HWND родительского окна
ID элемента (преобразуется в HMENU)
HINSTANCE приложения
Дополнительный данные(обычно NULL)
Теперь осталось добавить обработку элементов управления. Логика взаимодействия с дочерними окнами реализуется в оконной процедуре через обработку сообщения WM_COMMAND. При взаимодействие с дочерним окном, посылается сообщение WM_COMMAND, поэтому обрабатывая его, нужно получить id элемента управления , получаем через младшее слово wParam (ну или используем макрос LOWORD(wParam)), а само сообщение для элемента интерфейса в старшем слове (HIWORD(wParam)). И дальше проверяем что за конкретный ид, сравнивая со всеми идами, а если нашли, то через сообщения для каждого конкретного элемента управления:
класс BUTTON
класс EDIT
класс LISTBOX
класс COMBOBOX
класс SCROLLBAR
класс STATIC
класс RichEdit20W
класс TRACKBAR_CLASS
класс PROGRESS_CLASS - обычно не отправляет уведомления
класс WC_TABCONTROL
класс WC_TREEVIEW
класс WC_LISTVIEW
класс WC_HEADER
класс HOTKEY_CLASS - обычно не отправляет уведомления
класс ANIMATION_CLASS - обычно не отправляет уведомления
класс DATETIMEPICK_CLASS
класс MONTHCAL_CLASS
класс TOOLBARCLASSNAME
класс STATUSCLASSNAME - обычно не отправляет уведомления
А так же к слову, есть сообщения которые можно отправлять элементу управления для манипуляции с ним(например получения размера и т.п.):
класс BUTTON
класс EDIT
класс LISTBOX
класс COMBOBOX
класс SCROLLBAR
класс STATIC
класс RichEdit20W
класс TRACKBAR_CLASS
класс PROGRESS_CLASS
класс WC_TABCONTROL
класс WC_TREEVIEW
класс WC_LISTVIEW
класс WC_HEADER
класс HOTKEY_CLASS
класс ANIMATION_CLASS
класс DATETIMEPICK_CLASS
класс MONTHCAL_CLASS
класс TOOLBARCLASSNAME
класс STATUSCLASSNAME
И вот такой вот простой пример:
#include <Windows.h> // Идентификатор элемента управления #define ID_BUTTON 1001 HWND hButton, hMainHwnd; LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_DESTROY: PostQuitMessage(0); break; case WM_COMMAND: { int id = LOWORD(wParam); int notificationCode = HIWORD(wParam); switch (id) { case ID_BUTTON: if (notificationCode == BN_CLICKED) { PostQuitMessage(0); } break; } } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex = { 0 }; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WindowProc; wcex.hInstance = hInstance; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszClassName = L"AllControlsDemo"; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wcex); hMainHwnd = CreateWindowEx( 0, L"AllControlsDemo", L"Демонстрация", WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, 1920, 1080, NULL, NULL, hInstance, NULL ); hButton = CreateWindowExW(0L, L"BUTTON", L"Закрыть приложение", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 200, 100, 180, 35, hMainHwnd, (HMENU)ID_BUTTON, hInstance, NULL); ShowWindow(hMainHwnd, nCmdShow); UpdateWindow(hMainHwnd); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; }На этом рассмотрение дочерних окон завершено. Все остальные элементы управления создаются и обрабатываются аналогичным образом, поэтому разбирать каждый случай отдельно не вижу необходимости. Если потребуются детальные примеры для конкретных элементов, напишите об этом в комментариях.
-
-
Владеемые окна, как и дочерние, имеют родительское окно, но отличаются тем, что при их создании нельзя указывать стиль WS_CHILD (иначе это будет дочернее окно). Внешне владеемое окно выглядит как обычное окно, но обладает следующими особенностями:
Может блокировать взаимодействие с окном-владельцем.
Закрывается автоматически вместе с владельцем.
Минимизируется вместе с владельцем.
Всегда находится поверх окна-владельца.
На этом всё. Думаю следующая статья будет посвящена уже графики.
AWE64
Да, покажем этим вайбкодерам на электроне где раки зимуют!