Win32 API. Окна
ОГЛАВЛЕНИЕ
Об окнах
Окна являются основным средством графической прикладной программы, базирующейся на Win32, которые взаимодействуют с пользователем и выполняют задачи, поэтому одной из первых задач графического приложения, базирующегося на Win32, является создание окна. Этот обзор описывает элементы прикладного программного интерфейса (API) Microsoft Win32, который прикладные программы используют, чтобы создавать и использовать окна; управлять связями между ними; а также размером, перемещением и отображением окна на экране дисплея.
Когда запускается Windows, он автоматически создает окно рабочего стола (desktop window). Окно рабочего стола - определяемое системой окно, которое окрашивает фон экрана и служит ядром для всех окон, отображаемых всеми прикладными программами.
Окно Рабочего стола использует точечный рисунок, чтобы прорисовывать фон экрана. Узор, создаваемый точечным рисунком называется обоями рабочего стола (desktop wallpaper). По умолчанию, окно рабочего стола использует точечный рисунок из файла .BMP, который определен в системном реестре, как обои рабочего стола.
Функция GetDesktopWindow возвращает дескриптор окна рабочего стола.
Прикладная программа конфигурации системы, типа аплета Панель Управления (Control Panel), изменяет настольные обои рабочего стола, используя функцию SystemParametersInfo с параметром wAction, установленным в SPI_SETDESKWALLPAPER и параметром lpvParam, определяющим имя файла растровой картинки. Тогда SystemParametersInfo загружает точечный рисунок из заданного файла, используя его, чтобы окрасить фон экрана, и вводит новое имя файла в системный реестр.
Окна прикладной программы
Каждая графическая, базирующаяся на Win32, прикладная программа создает, по крайней мере, одно окно, называемое главным окном (main window), которое служит как основное окно для прикладной программы. Это окно служит в качестве первичного интерфейса между пользователем и прикладной программой. Большинство прикладных программ создают также, или непосредственно, или косвенно, другие окна, выполняющие задачи, связанные с главным окном. Каждое окно действует как часть процесса в отображении на экране выводимой информации и приема вводимых данных от пользователя.
Когда Вы запускаете прикладную программу, система к тому же связывает кнопку панели задач с прикладной программой. Кнопка панели задач (taskbar button) содержит пиктограмму и заголовок программы. Когда прикладная программа активная, ее кнопка на панели задач отображается в нажатом состоянии.
Компоненты окна прикладной программы
Окно прикладной программы включает в себя такие элементы как, строка заголовка, стро-ка меню, меню окна (прежде известное как системное меню), кнопка свертывания окна, кнопка развертывания окна, кнопка восстановления, кнопка закрытия окна, рамка установки размеров, рабочая область, линейка горизонтальной прокрутки и линейка вертикальной прокрутки. Главное окно прикладной программы обычно включает в себя все эти компоненты.
Строка заголовка (title bar) отображает на экране заданную прикладной программой пиктограмму и строку текста; обычно текст определяет имя прикладной программы или указывает предназначение окна. Прикладная программа определяет пиктограмму и текст, когда создается окно. К тому же, строка заголовка делает возможным для пользователя перемещение окна, используя мышь или другое устройство управления позицией.Большинство прикладных программ включает в себя строку меню (menu bar), которая перечисляет команды, поддерживаемые прикладной программой. Пункты в строке меню представляют основные категории команд. Выбор пункта в строке меню обычно открывает выскакивающее меню, чьи пункты соответствуют задачам внутри данной категории. Выбирая команду, пользователь направляет прикладную программу на выполнение задачи.
Меню окна (window menu) создается и управляется при помощи Windows. Оно содержит стандартный набор пунктов меню, которые, когда выбираются пользователем, устанавливают размер или позицию окна, закрывают прикладную программу или выполняют задачи. Для получения дополнительной информации о меню и меню окна, см. статью Меню.
Когда Вы щелкаете мышью по кнопке развертывания или свертывания окна, она воздействует на размер и позицию окна. Когда пользователь щелкает мышью по кнопке развертывания (maximize button) окна, Windows увеличивает окно до размеров экрана и располагает окно так, что оно закрывает весь рабочий стол, минус панель задач. В то же самое время, Windows заменяет кнопку развертывания окна на кнопку восстановления прежнего размера. Кнопка восстановления (restore button)- точечный рисунок, по которому когда щелкнешь мышью, восстанавливает окно в его предыдущем размере и позиции.
Когда пользователь щелкает мышью по кнопке свертывания (minimize button) окна, Windows уменьшает окно до размера кнопки его панели задач, помещает окно над кнопкой панели задач и отображает на экране кнопку панели задач в ее нормальном состоянии. Чтобы восстановить прикладную программу в её предыдущем размере и позиции, щелкните мышью по её кнопке на панели задач.
Рамка установки размеров (sizing border) - зона по периметру окна, которая дает возможность пользователю изменять по величине окно, используя мышь или другое устройство управления позицией.
Рабочая область (client area) - часть окна, где прикладная программа показывает на экране выводимую информацию, к примеру, текст или графику. Например, прикладная программа настольных издательских средств отображает в рабочей области текущую страницу документа. Прикладная программа должна предоставить функцию, вызываемую оконной процедурой, чтобы обрабатывать вводимые в окно данные и показывать в рабочей области выводимую информацию. Для получения дополнительной информации об оконных процедурах, см. статью Оконные процедуры.
Линейка горизонтальной (horizontal scroll bar) и вертикальной (vertical scroll bar) прокрутки преобразуют ввод данных от мыши или клавиатуры в значения, которые прикладная программа использует, чтобы передвигать содержимое рабочей области по горизонтали или вертикали. Например, прикладная программа обработки текстов, которая отображает длинный документ, обычно предоставляет линейку вертикальной прокрутки, чтобы дать возможность пользователю перемещаться вверх и вниз по документу.
Строка заголовка, строка меню, меню окна, кнопки свертывания и развертывания окна, установка размера рамки и линейки прокрутки, рассматриваются в собирательном значении как не рабочая область (nonclient area) окна. Windows управляет большинством аспектов не рабочей области; прикладная программа управляет всем остальным, что касается окна. В частности, прикладная программа управляет видом и поведением рабочей области.
Элементы управления, диалоговые окна и окна сообщений
Прикладная программа использует несколько типов окон в дополнение к его основному окну, включая элементы управления, диалоговые окна и окна сообщений.
Элемент управления (control) - окно, которое прикладная программа использует, чтобы получить конретную информацию от пользователя, такую как имя файла, чтобы его открыть или нужныйный размер выбранного текста в пунктах. Прикладные программы также используют элементы управления, чтобы получить информацию, необходимую для управления специфическими свойствами прикладной программы. Например, прикладная программа обработки текстов обычно предоставляет элемент управления, который позволяет пользователю включать и выключать автоматический перенос слов. Для получения дополнительной информации об элементах управления, см. статью Элементы управления.
Элементы управления используется всегда вместе с другим окном - обычно, диалоговым окном. Диалоговое окно (dialog box) является окном, которое содержит один или большее количество элементов управления. Прикладная программа использует диалоговое окно, чтобы запросить у пользователя ввода данных, необходимых для завершения команды. Например, прикладная программа, которая включает команду, чтобы открыть файл, должна показать на экране диалоговое окно, включающее в себя элементы управления, где пользователь конкретно определяет путь и имя файла.
Окно сообщений (message box) - окно, которое показывает на экране примечание, предостережение, или предупреждение пользователю. Например, окно сообщений может сообщать пользователю о проблеме, с которой прикладная программа столкнулась при выполнении задачи.
Диалоговые окна и окна сообщений обычно не используют тот же самый набор компонентов окна, как это делает главное окно. Чаще всего они имеют строку заголовка, меню окна, рамку (не изменяющую размеров) и рабочую область, но в них обычно нет строки меню, кнопок свертывания и развертывания. Для получения дополнительной информации о диалоговых окнах и окнах сообщений, см. Диалоговые окна.
Z-последовательность (Z Order)
Z-последовательность (Z order) окна обозначает позицию окна в стеке перекрывающихся окон. Этот оконный стек ориентируется по воображаемой оси, z-оси (оси аппликат), уходящей за пределы экрана. Окно наверху Z-последовательности перекрывает все другие окна. Окно внизу Z-последовательности перекрыто всеми другими окнами.
Windows Z-последовательность сохраняет в обычном списке. Добавляя окна в Z-последовательность, она основывается на том, что в любом случае они самые верхние окна, окна верхнего уровня или дочерние окна. Самое верхнее окно (topmost window) накладывается на все другие не самые верхние окна, независимо от того, является ли они активными или приоритетными окнами. Самое верхнее окно имеет стиль WS_EX_TOPMOST. Все самые верхние окна появляются в Z-последовательности перед любыми не самыми верхними окнами. Дочернее окно сгруппировано со своим родителем в Z-последовательности.
Когда прикладная программа создает окно, Windows помещает его наверху Z-последовательности для окон того же самого типа. Вы можете использовать функцию BringWindowToTop, чтобы перенести окно в верхнюю часть Z-последовательности для окон того же самого типа. Вы можете перестраивать Z-последовательность, используя функции SetWindowPos и DeferWindowPos.
Пользователь изменяет порядок Z-последовательности, активизируя различные окна. Windows устанавливает активное окно наверху Z-последовательности для окон того же самого типа. Когда окно переходит в верхнюю часть Z-последовательности, его дочерние окна делают это также. Вы можете использовать функцию GetTopWindow, чтобы отыскать все дочерние окна родительского окна и возвратить дескриптор дочернего окна, которое является самым высоким в Z-последовательности. Функция GetNextWindow извлекает данные о дескрипторе следующего или предыдущего окна в Z-последовательности.
Создание окна
Прикладная программа создает свои окна (включая основное окно) используя функцию CreateWindow или CreateWindowEx, и обеспечивает Windows информацией, которая требуется, чтобы определить атрибуты окна. Функция CreateWindowEx имеет параметр, dwExStyle, которого у функции CreateWindow нет; в остальном, функции идентичны. Фактически, CreateWindow просто вызывает CreateWindowEx, устанавливая параметр dwExStyle в ноль. По этой причине, оставшаяся часть этого краткого обзора относится только к CreateWindowEx.
Win32 API предусматривает дополнительные функции - включая DialogBox, CreateDialog, и MessageBox - для создания окон специального назначения, таких как диалоговые окна и окна сообщений. Для получения дополнительной информации об этих функциях, см. Диалоговые окна.
Атрибуты окна
Прикладная программа, когда создается окно, должна предоставить следующую информацию:
Класс окна (Window class)
Имя окна (Window name)
Стиль окна (Window style)
Родительское окно или окно владелец
Размеры
Размещение
Позицию на экране
Идентификатор дочернего окна или дескриптор меню
Дескриптор экземпляра
Данные для создания
В разделах ниже описываются эти атрибуты.
Класс окна
Каждое окно принадлежит определенному классу окна. Прикладная программа должна зарегистрировать класс окна перед созданием любого окна этого класса. Класс окна (window class) определяет большинство аспектов внешнего вида и поведения. Главный компонент класса окна - это оконная процедура (window procedure), функция которой получать и обрабатывать все вводимые данные и запросы, посланные окну. Окна предоставляют входные данные и запросы в форме сообщений (messages). Для большей информации о классах окна, оконных процедурах или сообщениях смотрите Классы окна, Оконные процедуры или Сообщения и Очереди сообщений.
Имя окна
Окно может иметь имя. Имя окна (window name) (называемое также оконный текст (window text)) - это текстовая строка, которая идентифицирует окно для пользователя. Главное окно, диалоговое окно или окно сообщения, если представлено, обычно показывает свое имя окна в своей строке заголовка. Для элемента управления внешний вид имени окна зависит от класса элементов управления. Кнопка, поле редактирования или статический элемент управления отображают свое оконное имя внутри прямоугольника, который занимает элемент управлением. Окно со списком, комбинированное окно или статический элемент управления не показывают имя своего окна.
Программа использует функцию SetWindowText, чтобы изменить имя окна после того, как окно создано. Она использует функции GetWindowTextLength и GetWindowText, чтобы сделать выборку текущего текста имени окна.
Стиль окна
Каждое окно имеет один или несколько стилей окна. Стиль окна (window style) - это име-нованная константа, которая определяет аспекты внешнего вида и поведения окна, которые не определяет класс окна. Например, класс SCROLLBAR создает линейку прокрутки, а стили SBS_HORZ и SBS_VERT определяют создание или горизонтальной или вертикальной линейки прокрутки. Несколько стилей окна применяют все окна, но большинство их применяют окна конкретного класса окна. Окна и, до некоторой степени, оконная процедура класса, интерпретируют стили.
Родительское или самостоятельное окно
Окно может иметь родительское окно. Окно, которое имеет родительское окно, называется дочерним окном (child window). Родительское окно (parent window) предоставляет систему координат, которая используется для позиционирования дочернего окна. Наличие родительского окна воздействует на аспекты внешнего вида окна; например, дочернее окно обрезается так, что-бы ни одна часть дочернего окна не могла появиться вне рамок своего родительского окна. Окно, у которого нет родительского окна или родитель которого самое главное окно, называется окном верхнего уровня (top-level window). Прикладная программа использует функцию EnumWindows, чтобы получить дескриптор каждого из своих окон верхнего уровня. Функция EnumWindows, в свою очередь, передает дескриптор каждого окна верхнего уровня в определенную программой функцию повторного вызова EnumWindowsProc.
Окно может иметь или принадлежать другому окну. Находящееся в собственности окно всегда появляется перед окном его владельца, скрывается, когда окно его владельца сворачивается и разрушается, когда окно его владельца разрушается.
Расположение, размер и позиция в Z-последовательности
Каждое окно имеет расположение, размер и позицию в Z-последовательности. Расположение - это координаты верхнего левого угла окна, относительно верхнего левого угла экрана или, в случае дочернего окна, верхнего левого угла рабочей области родителя. Размер окна - это его ширина и высота, измеряемая в пикселях. Позиция окна в Z-последовательности (Z order) - это позиция окна в стеке перекрывающихся окон. Для получения дополнительной информации, см "1.6 Z-последовательность (Z Order)".
Идентификатор Дочернего окна или дескриптор Меню
Дочернее окно может иметь идентификатор дочернего окна (child-window identifier), уникальное значение определенное программой, связанное с дочерним окном. Идентификаторы дочернего окна особенно полезны в прикладных программах, которые создают многочисленные дочерние окна. При создании дочернего окна, прикладная программа определяет идентификатор дочернего окна. После создания окна, прикладная программа может изменять идентификатор окна, используя функцию SetWindowLong, или может отыскать идентификатор, используя функцию GetWindowLong.
Каждое окно, за исключением дочернего окна, может иметь меню. Прикладная программа может включать в себя меню, путем предоставления дескриптора меню, или при регистрации класса окна, или при создании окна.
Дескриптор экземпляра
Каждая базирующаяся на Win32 прикладная программа имеет дескриптор связанного с ней экземпляра. Windows обеспечивает программу дескриптором экземпляра, когда она стартует. Поскольку он может запускать многочисленные копии одной и той же программы, Windows использует дескрипторы экземпляра внутри себя, чтобы отличить один экземпляр прикладной программы из другого. Прикладная программа должна определить дескриптор экземпляра во многих различных окнах, включая и те, которые создаются окнами.
Данные создания
Каждое окно может иметь определяемые программой данные создания, связанные с ней. Когда создано первое окно, Windows передает указатель на данные в оконную процедуру создаваемого окна. Оконная процедура использует эти данные, чтобы инициализировать определяемые программой переменные.
Дескрипторы окна
После создания окна, создающая функция возвращает дескриптор окна (window handle), который уникально идентифицирует окно. Прикладная программа использует этот дескриптор в других функциях, чтобы направить их действия на это окно. Дескриптор окна имеет тип данных HWND; прикладная программа должна использовать этот тип при объявлении переменной, которая содержит в себе дескриптор окна.
Win32 API включает в себя несколько специальных констант, которые могут заменять дескриптор окна в некоторых функциях. Например, прикладная программа может использовать HWND_TOPMOST в функции SendMessageTimeout, HWND_BROADCAST в функции SendMessage, или HWND_DESKTOP в функции MapWindowPoints.
Хотя константа ПУСТО (NULL) - не дескриптор окна, Вы можете использовать её в некоторых функциях, чтобы определить, нет ли воздействия на какое-либо окно. Например, установив значение ПУСТО (NULL) в параметре hwndParent функции CreateWindowEx, создается окно, у которого нет какого либо родителя или владельца. Некоторые функции могут возвращать значение ПУСТО (NULL) вместо дескриптора, указывая, что данное действие не применяется ни к какому окну.
Прикладная программа может использовать функцию FindWindow, чтобы обнаружить, существует ли в системе окно с определенным именем класса или именем окна. Если такое окно существует, FindWindow возвращает дескриптор окна. Чтобы ограничивать поиск в дочерних окнах отдельной прикладной программы, используйте функцию FindWindowEx. Функция IsWindow определяет, правильно ли идентифицирует дескриптор окна существующее окно.
Создание Главного окна
Каждая базирующаяся на Win32 прикладная программа должна иметь функцию WinMain как свою точку входа. Функция WinMain выполняет ряд задач, включая регистрацию класса окна для главного окна и создание этого главного окна. Функция WinMain регистрирует класс главного окна, путем вызова функции RegisterClass, и создает главное окно, вызывая функцию CreateWindowEx.
Проблема Мобильности Точка входа в программу не должна называться WinMain.
Ваша функция WinMain может также ограничить вашу прикладную программу единственным экземпляром. Создайте именованный mutex-объект (объект-статист), используя функцию CreateMutex. Если функция GetLastError возвращает ERROR_ALREADY_EXISTS, другой образец вашей прикладной программы существует (он создан mutex-объектом), и Вы должны выйти из вашей WinMain.
Windows автоматически не отображает на экране главное окно после его создания; чтобы отобразить его прикладная программа должна использовать функцию ShowWindow. После создания главного окна, функция прикладной программы WinMain вызывает ShowWindow, чтобы передать ей два параметра: дескриптор главного окна и флажок, определяющий, должно ли основное окно быть свернуто или развернуто, когда оно отображается в первый раз. Обычно, флажок может быть установлен для любой из констант, начинающихся SW_ префиксом. Однако, когда вызывается функция ShowWindow, чтобы показать главное окно прикладной программы, флажок должен быть установлен в SW_SHOWDEFAULT. Этот флажок сообщает, чтобы Windows отобразил окно как определено программой, которая запустила прикладную программу.
Если окно создано как окно Уникода (Unicode), оно принимает только сообщения в Уникоде (Unicode). Чтобы определить, является ли окно - окном Уникода (Unicode), вызывается функция IsWindowUnicode.
Сообщения, создающие окно
Когда создается какое-либо окно, Windows передает сообщения оконной процедуре для окна. Windows передает сообщение WM_NCCREATE после создания нерабочей области окна и сообщение WM_CREATE после создания рабочей области. Оба сообщения включают в себя указатель на структуру CREATESTRUCT, которая содержит всю информацию, определенную в функции CreateWindowEx. Обычно, оконная процедура выполняет задачу инициализации после приема этих сообщений.
При создании дочернего окна, Windows, после отправки сообщений WM_NCCREATE и WM_CREATE, посылает родительскому окну сообщение WM_PARENTNOTIFY. Он также посылает и другие сообщения при создании окна. Число и порядок этих сообщений зависят от класса окна и стиля и функций, используемых для создания окна. Эти сообщения описаны в других разделах этого справочного файла.
Многопотоковые прикладные программы
Базирующаяся на Win32 прикладная программа может иметь многочисленные потоки выполнения, и каждый поток может создавать окна. Поток, который создает окно, должен содержать код для его оконной процедуры.
Прикладная программа может использовать функцию EnumThreadWindows, чтобы перечислить окна, созданные отдельным потоком. Эта функция, в свою очередь, передает дескриптор каждого окна потока в определенную прикладной программой функцию повторного вызова, EnumThreadWndProc.
Функция GetWindowThreadProcessId возвращает идентификатор потока, который создал отдельное окно.
Чтобы установить состояние вида окна, созданного другим потоком, используйте функцию ShowWindowAsync.
Общие стили окна
Win32 API обеспечивает общие стили окна и определенные классом стили окна. Общие стили окон представляются константами, которые начинаются с префикса WS_; они могут быть объединены оператором OR (ИЛИ), чтобы формировать различные типы окон, включая главные окна, диалоговые окна и дочерние окна. Определенные классом стили окна определяют вид и поведение окон, принадлежащих к предопределенным классам элемента управления, таких как окна редактирования и окна списков. Этот обзор описывает общие стили окна.
Прикладная программа обычно устанавливает стили окна при создании окон. Она может также устанавливать стили после создания окна, используя функцию SetWindowLong.
Перекрывающее окно
Перекрывающее окно (overlapped window) - окно верхнего уровня, которое имеет строку заголовка, рамку и рабочую область; оно, как предполагается, служит как главное окно прикладной программы. Оно также может иметь меню окна, кнопки свертывания и развертывания окна и линейки прокрутки. Перекрывающее окно, используемое как главное окно, обычно включает все эти компоненты.
Определяя стиль WS_OVERLAPPED или WS_OVERLAPPEDWINDOW в функции CreateWindowEx, прикладная программа создает перекрывающее окно. Если Вы используете стиль WS_OVERLAPPED, окно имеет строку заголовка и рамку. Если Вы используете WS_OVERLAPPEDWINDOW стиль, окно имеет строку заголовка, устанавливающую размеры окна рамку, меню окна и кнопки свертывания и развертывания окна.
Выскакивающее Окно
Выскакивающее окно (pop-up window) - специальный тип перекрывающего окна, используемого для диалоговых окон, окон сообщений, и других временных окон, которые появляются снаружи главного окна прикладной программы. Строки заголовка для выскакивающих окон необязательны; иначе, выскакивающие окна - такие же, как и перекрывающие окна стиля WS_OVERLAPPED.
Вы создаете выскакивающее окно, определяя стиль WS_POPUP в функции CreateWindowEx. Чтобы включать строку заголовка, определите стиль WS_CAPTION. Используйте стиль WS_POPUPWINDOW, чтобы создать выскакивающее окно, которое имеет рамку и меню окна. Стиль WS_CAPTION должен быть объединен со стилем WS_POPUPWINDOW, чтобы сделать меню окна видимым.
Дочернее окно
Дочернее окно (child window) имеет стиль WS_CHILD и ограничено рабочей областью его родительского окна. Прикладная программа обычно использует дочерние окна, чтобы поделить рабочую область родительского окна на функциональные области. Вы создаете дочернее окно, определяя стиль WS_CHILD в функции CreateWindowEx.
Дочернее окно должно иметь родительское окно. Родительское окно может быть перекрывающим окном, выскакивающим окном или даже другим дочерним окном. Вы определяете родительское окно, когда Вы вызываете CreateWindowEx. Если Вы определяете стиль WS_CHILD в CreateWindowEx, но не определяете родительское окно, Windows не создает окно.
Дочернее окно имеет рабочую область, но никаких других функций, если они явно не затребованы. Прикладная программа может затребовать строку заголовка, меню окна, кнопки свертывания и развертывания окна, рамку и линейки прокрутки для дочернего окна, но дочернее окно не может иметь меню. Если прикладная программа определяет дескриптор меню, или когда она регистрирует класс дочернего окна, или когда создает дочернее окно, дескриптор меню игнорируется.
Позиционирование
Windows всегда устанавливает дочернее окно относительно верхнего левого угла рабочей области родительского окна. Никакая часть дочернего окна когда-либо не появляется снаружи рамок его родительского окна. Если прикладная программа создает дочернее окно, которое является большим чем родительское окно или устанавливает дочернее окно так, чтобы некоторые или все дочерние окна располагаются вне рамок родителя, Windows отсекает дочернее окно; то есть часть снаружи рабочей области родительского окна не отображается. Действия, которые воздействуют на родительское окно, могут также воздействовать на дочернее окно, следующим образом.
Родительское окно Дочернее окно
Разрушение Разрушение до того, как будет разрушено родительское окно.
Сокрытие Сокрытие до того как будет скрыто родительское окно.
Дочернее окно видно лишь тогда, когда видно родительское окно.
Перемещение Перемещается с рабочей областью родительского окна.
Дочернее окно ответственно за закрашивание его рабочей области после перемещения.
Видимость Показывается после того, как показалось родительское окно.
Закрепление
Windows автоматически не закрепляет дочернее окно с рабочей областью родительского окна. Это означает, что родительское окно делает прорисовку поверх дочернего окна, если оно выполняет какое-либо рисование, в том же самом месте, где дочернее окно. Однако, Windows скрепляет дочернее окно с рабочей областью родительского окна, если родительское окно имеет стиль WS_CLIPCHILDREN. Если дочернее окно закреплено, родительское окно не может рисовать поверх его.
Дочернее окно может накладываться на другие дочерние окна в той же самой рабочей области. Дочернее окно, которое разделяет то же самое родительское окно с одним или большим количеством других дочерних окон, называется сестринским окном (sibling window). Сестринские окна могут рисовать в рабочей области друг друга, если одно из дочерних окон не имеет стиля WS_CLIPSIBLINGS. Если дочернее окно имеет этот стиль, любая часть его сестринского окна, которое находится внутри дочернего окна, закрепляется.
Если окно имеет стиль WS_CLIPCHILDREN или WS_CLIPSIBLINGS, происходит небольшая потеря в эффективности. Каждое окно занимает системные ресурсы, так что прикладная программа не должна использовать дочерние окна беспорядочно. Для самой лучшей эффективности, прикладная программа, которой нужно логически поделить свое главное окно, должна сделать это в оконной процедуре главного окна скорее, чем используемые дочерние окна.
Взаимоотношение с родительским окном
Прикладная программа может изменять родительское окно существующего дочернего окна, вызывая функцию SetParent. В этом случае, Windows удаляет дочернее окно из рабочей области старого родительского окна и перемещает его в рабочую область нового родительского окна. Если SetParent определяет значение дескриптора ПУСТО (NULL), окно рабочего стола становится новым родительским окном. В этом случае, дочернее окно рисуется в самом главном окне, вне рамок любого другого окна. Функция GetParent восстанавливает дескриптор родительского окна для дочернего окна.
Родительское окно уступает часть своей рабочей области дочернему окну, и дочернее окно принимает всю вводимую информацию для этой области. Класс окна не должен быть тот же самый для каждого из дочерних окон родительского окна. Это означает, что прикладная программа может заполнять родительское окно дочерними окнами, которые выглядят поразному и выполняют различные задачи. Например, диалоговое окно может содержать много типов элементов управления, каждое из них дочернее окно, которое принимает различные типы данных от пользователя.
Дочернее окно имеет только одно родительское окно, но родитель может иметь любое число дочерних окон. Каждое дочернее окно, в свою очередь, может иметь дочерние окна. В этой цепочке окон, каждое дочернее окно называется порожденным окном первоначального родительского окна. Прикладная программа использует функцию IsChild, чтобы обнаружить, является ли данное окно дочерним окном или порожденным окном данного родительского окна.
Функция EnumChildWindows перечисляет дочерние окна родительского окна. Затем, EnumChildWindows передает дескриптор каждого дочернего окна в определенную прикладной программой функцию повторного вызова. Порожденные окна данного родительского окна также перечисляются.
Сообщения
Windows передает входящие сообщения дочернего окна непосредственно в дочернее окно; сообщения не передаются через родительское окно. Единственная исключительная ситуация является той, если дочернее окно было заблокировано функцией EnableWindow. В этом случае, Windows передает любые входные сообщения, которые пошли бы в дочернее окно в родительское окно. Это разрешает родительскому окну проверять входящие сообщения и, в случае необходимости, допускать их к дочернему окну.
Дочернее окно может иметь уникальный целочисленный идентификатор. Идентификаторы дочернего окна важны при работе с окнами элементов управления. Прикладная программа направляет действие элементов управления, посылая ему сообщения. Прикладная программа использует идентификаторы элементов управления дочернего окна, чтобы направлять сообщения в элемент управления. Кроме того, элемент управления посылает уведомительные сообщения своему родительскому окну. Уведомительное сообщение включает в себя идентификатор элемента управления дочернего окна, который родитель используют для определения, какому элементу управления послано сообщение. Прикладная программа определяет идентификатор дочернего окна для других типов дочерних окон, путем установки значения параметра hmenu функции CreateWindowEx скорее, чем дескриптор меню.
Рамка окна
Win32 API предоставляет нижеследующие стили рамки окна.
- WS_BORDER - Создает окно с рамкой из тонких линий.
- WS_DLGFRAME - Создает окно с двойной рамкой, стиль обычно используемый диалоговыми окнами. Окно с этим стилем не может иметь строку заголовка.
- WS_EX_DLGMODALFRAME - Создает окно с двойной рамкой. В отличие от WS_DLGFRAME стиля, прикладная программа может также определить WS_CAPTION стиль, чтобы создать строку заголовка для окна.
- WS_EX_STATICEDGE - Создает окно с трехмерным стилем рамки, предназначаемым для использования элементов, в которые нет доступа для вводимой информации пользователем.
- WS_THICKFRAME - Создает окно с изменяемыми размерами рамки.
Окно со стилем WS_OVERLAPPED или WS_POPUPWINDOW имеет по умолчанию стиль WS_BORDER. Один из оставшихся стилей рамки должен быть объединен со стилем WS_OVERLAPPED или WS_POPUPWINDOW, чтобы дать перекрывающему окну различные стили рамки.
Если для окна со стилем WS_POPUP или WS_CHILD стиль рамки не определен, система создает окно без рамки. Прикладная программа может использовать дочерние окна без рамок, чтобы разделить рабочую область родительского окна для сохранения разделов, невидимых для пользователя.
Компоненты нерабочей области
Нерабочая область окна может включать в себя строку заголовка, меню окна, кнопки свертывания и развертывания окна, установку размеров рамки окна, а также горизонтальную и вертикальную линейки прокрутки. Прикладная программа может создавать окно с одним или большим количеством этих компонентов, при помощи определения ниже перечисленных стилей в функции CreateWindowEx:
- WS_CAPTION - Создает окно, которое имеет строку заголовка (включает в себя стиль WS_BORDER).
- WS_HSCROLL - Создает окно, которое имеет горизонтальную линейку прокрутки.
- WS_MAXIMIZEBOX - Создает окно, которое имеет кнопку развертывания окна. Стиль не может быть объединен со стилем WS_EX_CONTEXTHELP.
- WS_MINIMIZEBOX - Создает окно, которое имеет кнопку свертывания окна. Стиль не может быть объединен со стилем WS_EX_CONTEXTHELP.
- WS_SYSMENU - Создает окно, которое имеет меню окна в своей строке заголовка. Должен быть также определен стиль WS_CAPTION.
- WS_VSCROLL - Создает окно, которое имеет вертикальную линейку прокрутки.
Исходное состояние окна
Ниже перечисленные стили определяют одно из двух состояний окна: разрешена его ра-бота или запрещена, видимое оно или невидимое, свернутое или развернутое.
WS_DISABLED - Создает окно, которое первоначально заблокировано. Заблокированное окно не может принимать вводимую информацию от пользователя.
WS_MAXIMIZE - Создает окно, которое первоначально развернуто.
WS_MINIMIZE - Создает окно, которое первоначально свернуто.
WS_VISIBLE - Создает окно, которое первоначально видимое.
Стили родительского и дочернего окон
Следующие стили воздействуют на взаимоотношение закрепления между родительским окном и его дочерними окнами, и между дочерним окном и его сестринскими окнами.
- WS_CLIPCHILDREN - Исключает область, занятую дочерними окнами при прорисовке внутри родительского окна. Используйте этот стиль при создании родительского окна.
- WS_CLIPSIBLINGS - Закрепляет дочерние окна относительно друг друга, то есть когда отдельное дочернее окно принимает сообщение WM_PAINT, стиль WS_CLIPSIBLINGS закрепляет все другие перекрывающие дочерние окна вне области дочернего окна, которое нужно модифицировать. Если WS_CLIPSIBLINGS не определен, и дочерние окна перекрываются, то возможно, что при прорисовке внутри рабочей области в одном из дочерних окон, произойдет прорисовка внутри рабочей области другого соседнего дочернего окна.
Расширенные стили
Следующие стили могут быть определены в параметре dwExStyle функции CreateWindowEx:
- WS_EX_ACCEPTFILES - Определяет, что окно, созданное с этим стилем принимает файлы информационной технологии "перетащи и вставь" (drag-and-drop).
- WS_EX_CONTEXTHELP - Включает вопросительный знак в строку заголовка окна. Когда пользователь щелкает мышью по вопросительному знаку, курсор изменяется на указатель с вопросительным знаком. Если пользователь затем щелкает мышью по дочернему окну, оно принимает сообщение WM_HELP. Дочернее окно должно передать сообщение в родительскую оконную процедуру, которая должна вызвать функцию WinHelp, использующую команду HELP_WM_HELP. Прикладная программа Справка (Help) отображает на экране выскакивающее окно, которое обычно содержит справку для дочернего окна. WS_EX_CONTEXTHELP не может использоваться со стилями WS_MAXIMIZEBOX или WS_MINIMIZEBOX.
- WS_EX_CONTROLPARENT - Позволяет пользователю перемещаться по дочерним окнам родительского окна, используя клавишу табуляции TAB.
- WS_EX_DLGMODALFRAME - Создает окно с двойной рамкой. В отличие от стиля WS_DLGFRAME, прикладная программа может также определять стиль WS_CAPTION, чтобы создать область заголовка для окна.
- WS_EX_NOPARENTNOTIFY - Определяет, что дочернее окно, созданное с этим стилем не будет посылать сообщение WM_PARENTNOTIFY своему родительскому окну, когда создается или разрушается.
- WS_EX_TOPMOST - Определяет, что окно, созданное с этим стилем, должно быть помещено выше всех не самых верхних окон и пребывать выше их даже тогда, когда окно дезактивировано.
- WS_EX_TOOLWINDOW - Создает инструментальные средства окна; то есть окно предполагается использовать как плавающую инструментальную панель. Окно инструментальных средств имеет строку заголовка короче, чем нормальная строка заголовка, а заголовок окна выводится, используя более мелкий шрифт. Окно инструментальных средств не появляется в панели задач или в окне, которые появляются, когда пользователь нажимает ALT+TAB.
Взаимоотношение Окон
Окно может быть находящимся во владении окном, заблокированным окном, приоритет-ным или фоновым окном. Имеется несколько различных способов, которые могут окно связывать с пользователем или другим окном.
Окна находящиеся во владении
Перекрывающее или выскакивающее окно может принадлежать другому перекрывающему или выскакивающему окну. Существующий хозяин несколько ограничивается действующим окном.
- Находящееся в собственности окно всегда выше его владельца в Z-последовательности.
- Windows автоматически разрушает находящееся в собственности окно, когда его владелец разрушен.
- Находящееся в собственности окно скрыто, когда его владелец свернут.
Только перекрывающее или выскакивающее окно может быть владельцем окна; дочернее окно не может быть им. Прикладная программа создает находящееся в собственности окно, определяя дескриптор владельца окна через параметр hwndParent функции CreateWindowEx, когда она создает окно в стиле WS_OVERLAPPED или WS_POPUP. Параметр hwndParent должен идентифицировать перекрывающее или выскакивающее окно. Если hwndParent идентифицирует дочернее окно, Windows назначает монопольное использование дочернего окна родительским окном верхнего уровня. После создания находящегося в собственности окна, прикладная программа не может передать монопольное использование окна к другому окну.
Диалоговые окна и окна сообщений - по умолчанию находящиеся в собственности окна. Прикладная программа определяет владельца окна при вызове функции, которая создает диалоговое окно или окно сообщений.
Прикладная программа может использовать функцию GetWindow с флажком GW_OWNER, чтобы отыскать дескриптор владельца окна.
Блокирование окон
Окно может быть заблокировано. Заблокированное окно (disabled window) не принимает вводную информацию через клавиатуру или мышь от пользователя, но оно может принимать сообщения от других окон, из других прикладных программ и из Windows. Прикладная программа обычно отключает окно, чтобы предотвратить использование окна пользователем. Например, прикладная программа может отключить кнопку команды в диалоговом окне, чтобы предотвратить выбор ее пользователем. Прикладная программа может открыть доступ к заблокированному окну в любое время; давая возможность окну восстановить нормальный ввод информации.
По умолчанию, окно, когда создается, включено в работу. Однако, прикладная программа может определить стиль WS_DISABLED, чтобы отключить новое окно. Прикладная программа включает или отключает существующее окно, используя функцию EnableWindow. Windows посылает сообщение WM_ENABLE окну, когда собирается изменить его включенное состояние. Прикладная программа может определить, включено ли окно, используя функцию IsWindowEnabled.
Когда дочернее окно заблокировано, Windows передает сообщения о вводимой информации от мыши в окне потомка в родительское окно. Родитель использует сообщения, чтобы определить, включать ли дочернее окно. Для получения дополнительной информации о вводе данных от мыши, см. Ввод данных от Мыши.
Только одно окно одновременно может принимать ввод данных от клавиатуры; в этом окне, как говорят, находится фокус клавиатуры. Если прикладная программа использует функцию EnableWindow, чтобы отключить окно с фокусом клавиатуры, окно, в дополнение к отключению, теряет фокус клавиатуры. Затем EnableWindow устанавливает фокус клавиатуры в значение ПУСТО (NULL), не обозначая, какое окно имеет фокус. Если дочернее окно, или другое порожденное окно, имеет фокус клавиатуры, порожденное окно теряет фокус тогда, когда родительское окно заблокировано. Для получения дополнительной информации о фокусе клавиатуры, см. Ввод данных с клавиатуры.
Приоритетные и фоновые окна
Каждый процесс может иметь многопоточное выполнение, и каждый поток может создавать окна. Поток, который создал окно, с которым пользователь в настоящее время работает, называется приоритетным потоком, а окно называется приоритетным окном (foreground window). Все другие потоки являются фоновыми, а созданные ими окна называются фоновыми окнами (background windows).
Каждый поток имеет приоритетный уровень, который определяет количество ПРОЦЕССОРНОГО ВРЕМЕНИ, которое поток занимает. Хотя прикладная программа может устанавливать приоритетный уровень своих потоков, обычно приоритетный поток имеет немного более высокий приоритетный уровень, чем фоновые потоки. Приоритетный поток, поскольку он имеет более высокий приоритет, занимает большее количество ПРОЦЕССОРНОГО ВРЕМЕНИ, чем фоновые потоки. Приоритетный поток имеет обычный базовый приоритет - 9; фоновый поток имеет обычный базовый приоритет - 7.
Пользователь устанавливает приоритетное окно, щелкая мышью по окну или, используя комбинацию клавиш ALT+TAB или ALT+ESC. Прикладная программа устанавливает приоритетное окно, используя функцию SetForegroundWindow. Если новое приоритетное окно - окно верхнего уровня, Windows активизирует его; иначе он активизирует связанное окно верхнего уровня. Прикладная программа отыскивает данные о дескрипторе приоритетного окна, используя функцию GetForegroundWindow. Чтобы проверить, является ли ваше окно прикладной программы активным, сравните дескриптор, возвращенный GetForegroundWindow с дескриптором окна вашей прикладной программы.
Состояние Показа
В любое данное время, окно может быть активным или неактивным; скрытым или видимым; свернутым, развернутым или восстановленным. Эти качества упоминаются одним словом как состояние показа (show state) окна.
Активное окно
Активное окно (active window) - окно верхнего уровня прикладной программы, с которым пользователь в настоящее время работает. Чтобы позволить пользователю легко идентифицировать активное окно, Windows помещает его вверху Z-последовательности и заменяет цвет его строки заголовка и рамки определенными системой цветами активного окна. Активным окном может быть только окно верхнего уровня. Когда пользователь работает с дочерним окном, Windows активизирует родительское окно верхнего уровня, связанное с дочерним окном.
Одновременно в системе может быть активным только одно окно верхнего уровня. Пользователь активизирует окно верхнего уровня, щелкая мышью по нему (или по одному из его дочерних окон) или используя комбинацию клавиш ALT+ESC или ALT+TAB. Прикладная программа активизирует окно верхнего уровня, вызывая функцию SetActiveWindow. В число других функций, которые могут заставлять Windows активизировать различные окна верхнего уровня, включены SetWindowPos, DeferWindowPos, SetWindowPlacement и DestroyWindow. Хотя прикладная программа может активизировать различное окно верхнего уровня в любое время, чтобы избежать запутывания пользователя, она поступает так только в ответ на действие пользователя. Прикладная программа использует функцию GetActiveWindow, чтобы найти данные о дескрипторе активного окна.
Когда активация переходит от окна верхнего уровня в одной из прикладных программ к окну верхнего уровня другой программы, Windows посылает сообщение WM_ACTIVATEAPP обеим прикладным программам, сообщая им об изменении. Когда активация переходит среди различных окон верхнего уровня в той же самой прикладной программе, Windows посылает обоим окнам сообщение WM_ACTIVATE.
Видимость
Окно может быть видимым или скрытым. Windows отображает на экране видимое окно (visible window). Она скрывает скрытое окно (hidden window), не прорисовывая его. Если окно видимое, пользователь может обеспечивать окно вводимой информацией и просматривать выводимую информацию в окне. Если окно скрытое, оно в действительности заблокировано. Скрытое окно может обрабатывать сообщения из Windows или из других окон, но оно не может обрабатывать вводимую информацию от пользователя или отображать на экране выводимую информацию. Прикладная программа устанавливает состояние видимости окна при создании окна. Позже, прикладная программа может изменять состояние видимости.
Окно видимо тогда, когда для окна установлен стиль WS_VISIBLE. По умолчанию, функция CreateWindowEx создает скрытое окно, если прикладная программа не определяет стиль WS_VISIBLE. Как правило, прикладная программа устанавливает стиль WS_VISIBLE после того, как она создала окно, чтобы хранить скрытыми от пользователя подробности процесса создания его. Например, прикладная программа может сохранять скрытым новое окно, пока она настраивает вид этого окна. Если стиль WS_VISIBLE определен в CreateWindowEx, Windows, после создания окна, посылает окну сообщение WM_SHOWWINDOW, но перед тем как показать его на экране.
Прикладная программа может определить, является ли окно видимым, используя функцию IsWindowVisible. Прикладная программа может показывать (делать видимым) или скрывать окно, используя функции ShowWindow, SetWindowPos, DeferWindowPos или SetWindowPlacement. Эти функции показывают или скрывают окно, устанавливая или удаляя WS_VISIBLE стиль для окна. Они также посылают сообщение WM_SHOWWINDOW окну перед показом или сокрытием его.
Когда окно владельца свернуто, Windows автоматически скрывает связанные с владельцем окна. Точно так же, когда окно владельца восстановлено, Windows автоматически показывает связанные с владельцем окна. В обоих случаях, Windows посылает сообщение WM_SHOWWINDOW окнам имеющим окно -"хозяина" перед сокрытием или показом их. Иногда, прикладной программе возможно надо скрыть находящиеся в собственности окна без необходимости свертывать или скрывать владельца. В этом случае, прикладная программа использует функцию ShowOwnedPopups. Эта функция устанавливает или удаляет стиль WS_VISIBLE для всех находящихся в собственности окон и посылает сообщение WM_SHOWWINDOW находящимся в собственности окнам перед сокрытием или показом их. Скрытие окна владельца не оказывает никакого эффекта на состоянии видимости находящихся в собственности окон.
Когда родительское окно видимое, связанные с ним дочерние окна также видимы. Точно так же, когда родительское окно скрыто, его дочерние окна также скрыты. Свертывание родительского окна не оказывает никакого эффекта на состояние видимости дочерних окон; то есть дочерние окна свертываются вместе с родителем, но стиль WS_VISIBLE не изменяется.
Даже если окно имеет стиль WS_VISIBLE, пользователь может быть не способен видеть окно на экране; другие окна могут полностью накладываться на него, или оно, возможно, было перемещено за края экрана. А также, видимое дочернее окно подчиненно правилам закрепления, установленными для него родительскими и дочерними взаимоотношениями. Если родительское окно окна не видимо, оно будет также невидимо. Если родительское окно перемещается за краями экрана, дочернее окно также перемещается, потому что дочернее окно выводится относительно верхнего левого угла родителя. Например, пользователь может перемещать родительское окно, содержащее дочернее окно достаточно далеко от края экрана, так что пользователь может быть не способен видеть дочернее окно, даже притом, что дочернее окно и его родительское окно оба имеют WS_VISIBLE стиль.
Свернутое, развернутое и восстановленное окно
Развернутое окно (maximized window)- окно, которое имеет стиль WS_MAXIMIZE. По умолчанию, Windows увеличивает развернутое окно так, чтобы оно заполнило экран или, в случае дочернего окна, рабочую область родительского окна. Хотя размеры окна могут быть установлены в тех же самых размерах развернутого окна, развернутое окно немного отличается. Windows автоматически перемещает строку заголовка окна в верхнюю часть экрана или в верхнюю часть рабочей области родительского окна. Windows также отключает опцию установки размеров рамки окна и возможность позиционирования окна в строке заголовка (так, чтобы пользователь не мог перемещать окно, перемещая строку заголовка).
Свернутое окно (minimized window) - окно, которое имеет стиль WS_MINIMIZE. По умолчанию, Windows уменьшает свернутое окно до размера его кнопки панели задач и перемещает свернутое окно в панель задач. Восстановленное окно (restored window) - окно, которое было возвращено к его прежним размерам и в позицию до свертывания или до развертывания. Если прикладная программа определяет стиль WS_MAXIMIZE или WS_MINIMIZE в функции CreateWindowEx, окно первоначально развернуто или свернуто. После создания окна, прикладная программа может использовать функцию CloseWindow, чтобы свернуть окно. Функция ArrangeIconicWindows упорядочивает пиктограммы на рабочем столе, или она упорядочивает свернутые дочерние окна в родительском окне. Функция OpenIcon восстанавливает свернутое окно в его предыдущих размерах и позиции.
Функция ShowWindow может свертывать, развертывать, или восстанавливать окно. Она может также устанавливать видимость окна и состояние активности. Функция SetWindowPlacement включает те же самые функциональные возможности, что и ShowWindow, но она может отменять свертывание, развертывание и восстановление позиции окна назначенные по умолчанию.
Функции IsZoomed и IsIconic определяют соответственно, развернуто ли или свернуто данное окно. Функция GetWindowPlacement восстанавливает свернутые, развернутые и восстановленные позиции окна, а также определяет состояние показа окна.
Когда Windows принимает команду, чтобы развернуть или восстановить свернутое окно, Windows посылает окну сообщение WM_QUERYOPEN. Если оконная процедура возвращает значение ЛОЖЬ(FALSE), Windows игнорирует команду Maximize (Развернуть) или Restore(Восстановить).
Windows автоматически устанавливает размер и позицию развернутого окна по определенным системой значениям по умолчанию для развернутого окна. Чтобы отменить эти значения по умолчанию, прикладная программа может или вызывать функцию SetWindowPlacement или обработать сообщение WM_GETMINMAXINFO, которое получаемое окном, когда Windows собирается развернуть его. WM_GETMINMAXINFO включает в себя указатель на структуру MINMAXINFO, содержащую значения Windows, используемые для установки развернутого размера и позиции. Замена этих значений отменяет значения по умолчанию.
Размер и позиция окна
Размер и позиция окна выражены как ограниченный прямоугольник, данный в координатах относительно экрана или родительского окна. Координаты окна верхнего уровня отсчитываются относительно верхнего левого угла экрана; координаты дочернего окна отсчитываются относи-тельно верхнего левого угла родительского окна. Прикладная программа определяет начальный размер окна и позицию, когда она создает окно, но она может изменять размер и расположение окна в любое время. Для получения дополнительной информации об ограниченных прямоугольниках, см. Заполненные Формы.
Размеры окна
Размеры окна (ширина и высота) даются в пикселях. Окно может иметь нулевую ширину или высоту. Если прикладная программа устанавливает нулевую ширину и высоту окна, Windows устанавливает размеры в заданных по умолчанию минимальных размерах окна. Чтобы узнать заданные по умолчанию минимальные размеры окна, прикладная программа использует функцию GetSystemMetrics с флажками SM_CYMIN и SM_CXMIN.
У прикладной программы может возникнуть необходимость создать окно с рабочей областью отдельного размера. Функции AdjustWindowRect и AdjustWindowRectEx вычисляют требуемый размер, базируясь на требуемых размерах рабочей области. Прикладная программа может передавать, полученные в результате, значения размера в функцию CreateWindowEx.
Прикладная программа может установить величину окна так, чтобы оно было чрезвычайно большое; однако, она не должно устанавливать величину окна так, чтобы оно было больше, чем экран. Перед установкой размера окна, прикладная программа должна проверить ширину и высоту экрана, используя GetSystemMetrics с флажками SM_CYSCREEN и SM_CXSCREEN.
Позиция (расположение) окна
Позиция окна определена как координаты его верхнего левого угла. Эти координаты, иногда называемые координатами окна, отсчитываются всегда относительно верхнего левого угла экрана или, для дочернего окна, от верхнего левого угла рабочей области родительского окна. Например, окно верхнего уровня, имеющее координаты (10,10) помещено на 10 пикселей вправо от верхнего левого угла экрана и на 10 пикселей вниз от него. Дочернее окно, имеющее координаты (10,10) помещено на 10 пикселей направо от верхнего левого угла рабочей области его родительского окна и на 10 пикселей вниз от него.
Функция WindowFromPoint отыскивает дескриптор окна, занимающего отдельное место на экране. Точно так же функции ChildWindowFromPoint и ChildWindowFromPointEx отыскивают дескриптор дочернего окна, занимающего отдельное место в рабочей области родительского окна. Хотя функция ChildWindowFromPointEx может игнорировать невидимые, заблокированные и прозрачные дочерние окна, то ChildWindowFromPoint это не может.
Размеры и позиция по умолчанию
Прикладная программа может позволить Windows вычислять начальный размер или позицию окна верхнего уровня, путем установки CW_USEDEFAULT в CreateWindowEx. Если прикладная программа устанавливает координаты окна в CW_USEDEFAULT и не создает никаких других окон верхнего уровня, Windows устанавливает позицию нового окна относительно верхнего левого угла экрана; иначе, она устанавливает позицию относительно позиции окна верхнего уровня, которое прикладная программа создала совсем недавно. Если параметры ширины и высоты установлены в CW_USEDEFAULT, Windows вычисляет размер нового окна. Если прикладная программа создала другие окна верхнего уровня, Windows базирует размеры нового окна на размере окна верхнего уровня прикладной программы созданного совсем недавно. Определение CW_USEDEFAULT, при создании дочернего или выскакивающего окна, заставляет Windows устанавливать размеры окна в заданных по умолчанию минимальных размерах окна.
Устанавливаемые размеры
Windows поддерживает минимальный и максимальный устанавливаемый размер для окна стиля WS_THICKFRAME; окно с этим стилем имеет рамку установки размеров окна. Минимальный устанавливаемый размер (minimum tracking size) - самый маленький размер окна, который пользователь, может сделать, перемещая рамку установки размеров окна. Точно так же максимальный устанавливаемый размер (maximum tracking size) - самый большой размер окна, который пользователь может сделать, перемещая рамку установки размеров окна.
Минимальные и максимальные устанавливаемые размеры окна устанавливаются в значениях, определенных системой по умолчанию, когда Windows создает окно. Прикладная программа может узнать значения по умолчанию и отменить их, обрабатывая сообщение WM_GETMINMAXINFO. Для получения дополнительной информации об этом сообщении, см. Сообщения о Размере и Позиции.
Системные команды
Прикладная программа, которая имеет меню окна, может изменять размер и позицию этого окна, посылая системные команды. Системные команды генерируются тогда, когда пользователь выбирает команды из меню окна. Прикладная программа может подражать действию пользователя, посылая в окно сообщение WM_SYSCOMMAND. Следующие системные команды воздействуют на размер и позицию окна.
- SC_CLOSE - Закрывает окно. Эта команда посылает сообщение WM_CLOSE окну. Окно выполняет любые шаги, необходимые, чтобы очистить и уничтожить себя.
- SC_MAXIMIZE - Разворачивает окно.
- SC_MINIMIZE - Свертывает окно.
- SC_RESTORE - Возвращает свернутое или развернутое окно в его предыдущие размеры и позицию.
- SC_SIZE - Запускает команду Размер (Size). Пользователь может изменять размеры окна, используя мышь или клавиатуру.
Функции размера и позиции
После создания окна, прикладная программа может устанавливать размер окна или позицию, вызывая одну из нескольких различных функций, среди которых SetWindowPlacement, MoveWindow, SetWindowPos и DeferWindowPos. SetWindowPlacement устанавливает позицию свернутого окна, позицию развернутого окна, восстанавливает размер и позицию окна и показывает его состояние. Функции MoveWindow и SetWindowPos похожи; обе устанавливают размер или позицию отдельного окна прикладной программы. Функция SetWindowPos включает в себя набор флажков, которые воздействуют на состояние показа окна; MoveWindow не включает в себя эти флажки. Используйте функции BeginDeferWindowPos, DeferWindowPos и EndDeferWindowPos, чтобы одновременно установить позицию ряда окон, включая размер, позицию, позицию в Z-последовательности и состояние показа.
Прикладная программа может отыскать координаты ограничительного прямоугольника окна, используя функцию GetWindowRect. GetWindowRect заполняет структуру RECT координатами верхних левых и нижних правых углов окна. Координаты, вычисляемые относительно верхнего левого угла экрана, те же самые для дочернего окна. Функции ScreenToClient или MapWindowPoints отображает экранные координаты ограничительного прямоугольника дочернего окна относительно координат рабочей области родительского окна.
Функция GetClientRect отыскивает координаты рабочей области окна. GetClientRect заполняет структуру RECT координатами верхних левых и нижних правых углов рабочей области, а координаты отсчитываемые относительно рабочей области самостоятельно. Это означает, что координаты верхнего левого угла рабочей области - всегда (0,0), а координаты нижнего правого угла - ширина и высота рабочей области.
Функция CascadeWindows располагает каскадом окна на рабочем столе или располагает каскадом дочерние окна определенного родительского окна. Функция TileWindows располагает окна на рабочем столе или дочерние окна определенного родительского окна в не перекрывающих друг друга положениях ("мозаикой").
Сообщения о размере и позиции
Windows посылает сообщение WM_GETMINMAXINFO окну, чей размер или позиция должны измениться. Например, сообщение посылается, когда пользователь выбирает из меню окна команду Переместить (Move) или Размер (Size) или щелкает мышью по рамке установки размеров окна или по строке заголовка; сообщение посылается также тогда, когда прикладная программа вызывает функцию SetWindowPos, чтобы переместить или установить величину окна. Сообщение WM_GETMINMAXINFO включает в себя указатель на структуру MINMAXINFO, содержащую по умолчанию развернутый размер и позицию для окна, а также заданные по умолчанию минимальный и максимальный устанавливаемые размеры. Прикладная программа может отменять значения по умолчанию, обрабатывая WM_GETMINMAXINFO и устанавливая соответствующие элементы MINMAXINFO. Чтобы принять WM_GETMINMAXINFO, окно должно иметь стиль WS_THICKFRAME или WS_CAPTION. Окно со стилем WS_THICKFRAME принимает это сообщение в ходе процесса создания окна, а также тогда, когда оно передвигается или устанавливается по размеру.
Windows посылает сообщение WM_WINDOWPOSCHANGING окну, чей размер, позиция, позиция в Z-последовательности или состояние показа собирается измениться. Это сообщение включает в себя указатель на структуру WINDOWPOS, которая определяет новый размер окна, позицию, позицию в Z-последовательности и состояние показа. Устанавливая элементы WINDOWPOS, прикладная программа может воздействовать на новый размер, позицию и вид окна.
После изменения размера окна, позиции, позиции в Z-последовательности или состояния показа, Windows посылает окну сообщение WM_WINDOWPOSCHANGED. Это сообщение включает в себя указатель на WINDOWPOS, который сообщает окну о его новых размерах, позиции, позиции в Z-последовательности и состоянии показа. Установка элементов структуры WINDOWPOS, которая передана вместе с WM_WINDOWPOSCHANGED, не влияет на окно. Окно, которое должно обработать сообщения WM_SIZE и WM_MOVE, должно передать WM_WINDOWPOSCHANGED в функцию DefWindowProc; иначе, Windows не посылает сообщения WM_SIZE и WM_MOVE в окно.
Windows посылает сообщение WM_NCCALCSIZE окну, когда окно создано или установлено по размеру. Windows использует это сообщение, чтобы вычислить размер рабочей области окна и позиции рабочей области относительно верхнего левого угла окна. Окно обычно передает это сообщение в заданную по умолчанию оконную процедуру; однако, это сообщение может быть полезно в прикладных программах, которые настраивают нерабочую область окна или сохраняют части рабочей области, когда окно устанавливается по размеру. Для получения дополнительной информации о размере окна, см. статью Закрашивание и Рисование.
Разрушение окна
Вообще, прикладная программа должна уничтожать все окна, которые она создает. Она делает это, используя функцию DestroyWindow. Когда окно разрушается, система скрывает его, если оно видимо, а затем удаляет любые внутренние данные, связанные с окном. Это действие лишает законной силы дескриптор окна, который больше не может использоваться прикладной программой.
Прикладная программа уничтожает многие из окон, которые она создает, вскоре после их создания. Например, прикладная программа обычно уничтожает окно блока диалога, как только прикладная программа получит достаточно вводимой информации от пользователя, чтобы продолжить выполнение своей задачи. Прикладная программа, в конечном счете, уничтожает основное окно прикладной программы (при завершении работы).
Перед разрушением окна, прикладная программа должна сохранить или удалить любые данные, связанные с окном, а также она должно освободить любые ресурсы системы, распределенные для окна. Если прикладная программа не освобождает ресурсы, Windows освободит любые ресурсы, не освобожденные прикладной программой.
Разрушение окна не воздействует на класс окна, из которого оно создано. Новые окна могут все еще создаваться, используя этот класс, а любые существующие окна этого класса продолжают функционировать. Разрушение окна также уничтожает порожденные им окна. Функция DestroyWindow посылает сообщение WM_DESTROY сначала окну, а затем его дочерним и порожденным окнам. Таким образом, все порожденные окна разрушаемого окна также разрушаются.
Когда пользователь выбирает команду Закрыть (Close), окно с меню окна принимает сообщение WM_CLOSE. Обрабатывая это сообщение, прикладная программа может запрашивать пользователя о подтверждении этого действия перед разрушением окна. Если пользователь подтверждает, что окно должно быть разрушено, прикладная программа может вызывать функцию DestroyWindow, чтобы уничтожить окно.
Если разрушаемое окно - активное, то и активность, и состояние фокуса перемещаются в другое окно. Окно, которое становится активным - следующее окно, как определено комбинацией клавиш ALT+ESC. Новое активное окно затем определяет, какое окно принимает фокус клавиатуры.
Использование окон
Примеры в этом разделе описывают, как выполнить следующие задачи:
- Создание основного окна
- Создание, перечисление и установка размеров дочерних окон
- Разрушение окна
Создание основного окна
Первое окно, которое создает прикладная программа - обычно основное окно(main window). Вы создаете основное окно, используя функцию CreateWindowEx, которая определяет класс, имя , стили окна, размер, позицию, дескриптор меню, дескриптор экземпляра и данные создания. Основное окно принадлежит определенному прикладной программой классу окна, таким образом, Вы должны зарегистрировать класс окна и предоставить оконную процедуру для класса перед созданием основного окна.Большинство прикладных программ обычно использует для создания основного окна стиль WS_OVERLAPPEDWINDOW. Этот стиль дает окну строку заголовка, меню окна, рамку установки размеров окна, кнопки свертывание и развертывания окна. Функция CreateWindowEx возвращает дескриптор, который уникально идентифицирует окно.
Следующий пример создает основное окно, принадлежащее к классу окна определенному прикладной программой. Имя окна, " Основное Окно ", появится в строке заголовка окна. Объединяя стили WS_VSCROLL и WS_HSCROLL со стилем WS_OVERLAPPEDWINDOW, прикладная программа создает основное окно с горизонтальными и вертикальными линейками прокрутки в дополнение к компонентам, предоставляемым стилем WS_OVERLAPPEDWINDOW. Четырехкратное повторение константы CW_USEDEFAULT устанавливает начальный размер и позицию окна в зна-чения, определенные системой по умолчанию. Устанавливая значение ПУСТО (NULL), вместо дескриптора меню, окно получит меню, определенное для класса окна.
HINSTANCE hinst;
HWND hwndMain;
// Создание основного окна.
hwndMain = CreateWindowEx(
0, // расширения стилей нет
"MainWClass", // имя класса
"Основное окно", // имя окна
WS_OVERLAPPEDWINDOW | // перекрывающее окно
WS_HSCROLL | // горизонтальная линейка прокрутки
WS_VSCROLL, // вертикальная линейка прокрутки
CW_USEDEFAULT, // горизонтальная позиция по умолчанию
CW_USEDEFAULT, // вертикальная позиция по умолчанию
CW_USEDEFAULT, // ширина по умолчанию
CW_USEDEFAULT, // высота по умолчанию
(HWND) NULL, // окно не родительское или
// имеющее в собственности окна
(HMENU) NULL, // используемый класс меню
hinstance, // дескриптор экземпляра
NULL); // нет данных создания окна
if (!hwndMain)
return FALSE;
// Показывает окно, использующее флажок, определенный программой,
// которая запускает прикладную программу и передает в приложение
// сообщение WM_PAINT.
ShowWindow(hwndMain, SW_SHOWDEFAULT);
UpdateWindow(hwndMain);
Обратите внимание, что предшествующий пример вызывает функцию ShowWindow после создания основного окна. Это сделано потому, что Windows автоматически не отображает на экране основное окно после его создания. Передавая флажок SW_SHOWDEFAULT в ShowWindow, прикладная программа позволяет программе, которая запустила приложение, установить начальное состояние показа основного окна. Функция UpdateWindow посылает окну свое первое сообщение WM_PAINT.
Создание, перечисление и изменение размеров дочерних окон
Вы можете поделить рабочую область окна на функционально-различные области, используя дочерние окна. Для создания дочернего окна, подобно созданию основного окна, Вы используете функцию CreateWindowEx. Чтобы создать окно определенного прикладной программой класса окна, Вы должны зарегистрировать класс окна и предоставить оконную процедуру перед созданием дочернего окна. Вы должны дать дочернему окну стиль WS_CHILD и определить родительское окно для дочернего окна, когда его создаете.Следующий пример делит рабочую область основного окна прикладной программы на три функциональные области, создавая три дочерних окна равного размера. Каждое дочернее окно имеет ту же самую высоту, что и рабочая область основного окна, однако каждое - третья часть его ширины. Основное окно создает дочерние окна в ответ на сообщение WM_CREATE, которое основное окно принимает в ходе своего собственного процесса создания. Поскольку каждое дочернее окно имеет стиль WS_BORDER, каждое из них имеет тонкую линию рамки. А также, по-скольку стиль WS_VISIBLE не определен, каждое дочернее окно первоначально скрыто. Обратите внимание также на то, что каждому дочернему окну назначен идентификатор дочернего окна.
Основное окно устанавливает величину и позицию дочерних окон в ответ на сообщение WM_SIZE, которое основное окно принимает, когда изменяются его размеры. В ответ на WM_SIZE, основное окно восстанавливает габариты своей рабочей области, используя функцию GetWindowRect, а затем передает габариты в функцию EnumChildWindows. В свою очередь, EnumChildWindows передает дескриптор каждого дочернего окна в определенную прикладной программой функцию повторного вызова EnumChildProc. Эта функция устанавливает размеры и позицию каждого дочернего окна, через вызов функции MoveWindow; размер и позиция основываются на габаритах рабочей области основного окна и на идентификаторе дочернего окна. Позже, EnumChildProc вызывает функцию ShowWindow, чтобы сделать окно видимым.
#define ID_FIRSTCHILD 100
#define ID_SECONDCHILD 101
#define ID_THIRDCHILD 102
LONG APIENTRY MainWndProc(hwnd, uMsg, wParam, lParam)
HWND hwnd;
UINT uMsg;
UINT wParam;
LONG lParam;
{
RECT rcClient;
int i;
switch(uMsg)
{
case WM_CREATE: // создание основного окна
// Создание трех невидимых дочерних окна
for (i = 0; i < 3; i++)
CreateWindowEx(0,"ChildWClass",(LPCTSTR) NULL,WS_CHILD | WS_BORDER,
0,0,0,0,hwnd,(HMENU) (int) (ID_FIRSTCHILD + i),hinst,NULL);
return 0;
case WM_SIZE: // изменение размеров основного окна
// Получает габариты рабочей области главного окна и перечисляет дочерние окна.
// Передает габариты в дочерние окна в ходе перечисления.
GetClientRect(hwnd, &rcClient);
EnumChildWindows(hwnd, EnumChildProc,(LPARAM) &rcClient);
return 0;
// Создание других сообщений.
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
BOOL CALLBACK EnumChildProc(hwndChild, lParam)
HWND hwndChild;
LPARAM lParam;
{
LPRECT rcParent;
int i, idChild;
// Восстановление идентификатора дочернего окна.
// Использовать его для установки дочернего окна.
idChild = GetWindowLong(hwndChild, GWL_ID);
if (idChild == ID_FIRSTCHILD)
i = 0;
else if (idChild == ID_SECONDCHILD)
i = 1;
else
i = 2;
// Размер и позиция дочернего окна.
rcParent = (LPRECT) lParam;
MoveWindow(hwndChild, (rcParent->right / 3) * i,0, rcParent->right / 3,rcParent->bottom,TRUE);
// Удостоверитесь, что дочернее окно видимо
ShowWindow(hwndChild, SW_SHOW);
return TRUE;
}
Разрушение окна
Вы можете использовать функцию DestroyWindow, чтобы уничтожить окно. Как правило, прикладная программа перед разрушением окна посылает сообщение WM_CLOSE, давая окну возможность запросить у пользователя подтверждение перед разрушением его. Окно, которое включает в себя автоматически меню окна, принимает сообщение WM_CLOSE, когда пользователь выбирает команду Закрыть (Close) из меню. Если пользователь подтверждает, что окно должно быть разрушено, прикладная программа вызывает DestroyWindow. Windows посылает окну сообщение WM_DESTROY после удаления его с экрана. В ответ на WM_DESTROY, окно сохраняет свои данные и освобождает любые ресурсы, которые выделила ему система. Основное окно завершает свою обработку WM_DESTROY, вызывая функцию PostQuitMessage, чтобы выйти из прикладной программы.Следующий пример показывает, как запросить подтверждение у пользователя перед разрушением окна. В ответ на WM_CLOSE, пример отображает на экране диалоговое окно, которое содержит кнопки Да (Yes) , OK и Прекратить (Cancel). Если пользователь щелкает мышью по кнопке Да (Yes), вызывается DestroyWindow; иначе, окно не разрушается. Поскольку разрушаемое окно - основное окно, пример вызывает PostQuitMessageWM_DESTROY.
case WM_CLOSE:
// Создаем окно сообщений. Если пользователь щелкает мышью
// по кнопке Да (Yes), основное окна разрушается.
if (MessageBox(hwnd, szConfirm, szAppName,
MB_YESNOCANCEL) == IDYES)
DestroyWindow(hwndMain);
else
return 0;
case WM_DESTROY:
// Регистрирует сообщение WM_QUIT, чтобы завершить выход из программы.
PostQuitMessage(0);
return 0;