Окна Windows

Автор: Roustem Galeev
Опубликовано: 19.12.2006
Версия текста: 1.4

Учебная программа «Windows»
Структура WNDCLASS
Значок окна (hIcon).
Курсор класса окна (hCursor).
Меню класса окна (lpszMenuName).
Фон окна (hbrBackground).
Стиль класса (style).
Главная функция окна (lpfnWndProc).
Функция CreateWindowEx()
Заголовок окна (lpWindowName).
Положение окна (x и y).
Размеры окна (nWidth и nHeight).
Меню окна (hMenu).
Родительское окно (hWndParent).
Имя класса окна (lpClassName).
Стиль окна (dwStyle).
Расширенный стиль окна (dwExStyle).
Отображение окна
Заключение

Учебная программа "Windows"
Исходные тексты учебной программы (VS2003)

Учебная программа «Windows»

В свое время, когда я только начинал осваивать хитрости программирования под Windows, мне пришла в голову мысль, что хорошо было бы создать учебную программу для экспериментирования с многочисленными параметрами используемых функций – чтобы не надо было каждый раз редактировать и компилировать заново исходный код «учебного» проекта, а можно было бы выбрать необходимые опции прямо в диалоговом окне и тут же увидеть результат. И через некоторое время я ее действительно создал.

После того, как я с ней наигрался, она пролежала несколько лет в архивах, пока недавно я не наткнулся на нее и не подумал, что, возможно, она могла бы пригодиться еще кому-нибудь. Так возникла идея предоставить эту программу всем желающим, сопроводив статьей с описанием самой учебной программы, а также тех экспериментов, которые я сам с ней проделывал.

Итак, учебная программа "Windows". Запустите программу «Windows.exe». Первым делом бросается в глаза какой-то код в рабочей области окна. О нем чуть позже, а сейчас изучим меню программы, которое состоит из пунктов «Файл», «Правка» и «Параметры». Меню «Файл» содержит пункты «Создать окно», «О программе...» и «Выход». Выберите пункт «Создать окно».

Появляется новое окно. Это полноценное окно с заголовком, имеющее в левом верхнем углу свой значок, при щелчке на котором появляется системное меню; в правом верхнем углу имеются кнопки свертывания, восстановления и разворачивания; размеры самого окна можно изменять, перетаскивая его рамку. Параметры окна заданы программой «Windows» по умолчанию. Точно такое же окно можно получить, если откомпилировать и запустить программу, код которой находится в рабочей области главного окна приложения.

Отображаемый в окне код можно скопировать в главный cpp-файл проекта приложения Win32 в VC6 и откомпилировать его, получив приложение, создающее такое же окно, как учебная программа. (Есть ряд опций учебной программы, при выборе которых скомпилировать такое приложение не получится; далее они оговорены особо.)

И наконец, главный пункт меню для наших экспериментов – «Параметры». Он содержит три пункта: «Класс окна...», «Окно...» и «Дополнительно...». Каждый из них вызывает диалоговое окно, позволяющее настроить значения полей структуры WNDCLASS, параметров функций CreateWindowEx(), ShowWindow() и даже код главной функции окна. Далее приводятся описания используемых структур, функций и возможностей по настройке.

Структура WNDCLASS

Напомним определение структуры WNDCLASS (листинг 1).

Листинг 1.
typedef struct _WNDCLASS { 
    UINT    style; 		//стиль класса окна
    WNDPROC lpfnWndProc; 	//указатель на функцию окна
    int     cbClsExtra; 	//число дополнительных байтов класса
    int     cbWndExtra; 	//число дополнительных байтов окна
    HANDLE  hInstance;		//дескриптор экземпляра приложения
    HICON   hIcon;		//дескриптор значка класса
    HCURSOR hCursor;		//дескриптор курсора класса
    HBRUSH  hbrBackground;	//кисть фона окна
    LPCTSTR lpszMenuName;	//указатель на имя ресурса меню
    LPCTSTR lpszClassName;	//указатель на имя класса
} WNDCLASS;

Программа позволяет настраивать значения всех полей структуры, кроме имени класса (lpszClassName), экземпляра приложения (hInstance), дополнительных байтов класса (cbClsExtra) и окна (cbWndExtra).

Значок окна (hIcon).

Значок можно выбрать на вкладке «Стиль и значок» диалогового окна «Параметры структуры WNDCLASS», которое вызывается при выборе пункта меню «Класс окна…» (рис. 1).


Рис. 1. Вкладка «Стиль и значок».

Поскольку программа «Windows» предназначена для изучения встроенных возможностей Windows, на вкладке «Стиль и значок» можно выбирать лишь стандартные значки. В качестве первого параметра функции LoadIcon() можно передать NULL; в этом случае система использует один из стандартных встроенных значков. Описание соответствующего значка отображается в диалоговом окне в виде всплывающей подсказки.

Задание

Запустите программу «Windows» и выберите в меню «Параметры» пункт «Класс окна...» и далее вкладку «Стиль и значок». Щелкните на кнопке «NULL», затем «Зарегистрировать окно». Обратите внимание, как изменилась строка «cls.hIcon» в окне программы. Создайте окно, выбрав соответствующий пункт из меню «Файл».

Если значок класса отсутствует, Windows9x использует значок своего логотипа (стандартный значок IDI_WINLOGO), а WindowsXP – значок приложения (IDI_APPLICATION).

Курсор класса окна (hCursor).

Курсор класса окна можно выбрать на вкладке «Курсор, меню, функция окна» диалогового окна «Параметры структуры WNDCLASS» (рис. 2).


Рис. 2. Вкладка «Курсор, меню, функция окна».

Если параметр hInstance функции LoadCursor() равен NULL, в зависимости от значения второго параметра загружается один из системных курсоров. Описание соответствующего курсора отображается во всплывающей подсказке диалогового окна.

Задание

Выберите на вкладке «Курсор, меню, функция окна» диалогового окна «Параметры структуры WNDCLASS» кнопку IDC_WAIT. Зарегистрируйте класс. Обратите внимание на изменение строки «cls.hCursor» в окне программы. Создайте новое окно.

Понаблюдайте, как система отслеживает положение курсора и меняет его форму - песочные часы появляются лишь тогда, когда указатель заходит в рабочую область окна. Теперь создайте еще одно окно. Можете изменить размеры окон, расположить их по-разному - в любом случае при попадании указателя в рабочую область любого из окон курсор приобретает форму песочных часов, потому что курсор является атрибутом именно класса окна, а оба созданных окна относятся к одному и тому же классу.

Задание

Закройте ранее созданные окна. На вкладке «Курсор, меню, функция окна» выберите кнопку «NULL» и зарегистрируйте класс. Создайте новое окно. «Входите» в окно с разных направлений - сбоку, снизу, сверху; проделайте это с разной скоростью.

Если курсор класса не задан, при попадании в область окна он сохраняет свою прежнюю форму. Поэтому если «заходить» сверху, это будет стандартная стрелка, если сбоку достаточно быстро - вертикальная черта, а если движение было достаточно медленным и курсор при пересечении границы окна успел принять форму двунаправленной стрелки, то она и останется. Сама двунаправленная стрелка в зависимости от места пересечения окна также будет разной.

Меню класса окна (lpszMenuName).

В отличие от значков и курсоров, меню для окна можно назначать в двух местах: при определении класса окна и при создании самого окна, в функции CreateWindowEx(). Меню класса - это меню по умолчанию, которое используется лишь тогда, когда меню не задано явно в функции CreateWindowEx().

Задание

Выберите вкладку «Курсор, меню, функция окна» диалогового окна «Параметры структуры WNDCLASS» (рис. 2) и щелкните на раскрывающемся списке «Меню». Выберите из списка «Экспериментальное». Зарегистрируйте класс. Обратите внимание, что в отображаемом коде изменилась не только строка «cls.lpszMenuName», но и появились операторы (начиная с «case WM_COMMAND:» в функции окна. Создайте окно.

Теперь у нашего окна есть простенькое меню с именем «EXPERIMENTAL» (как можно узнать из строки «cls.lpszMenuName») и двумя подменю: «Окно» и «Текст». Подменю «Окно» содержит пункт «Закрыть», позволяющий просто закрыть окно, а вот пункт «Вывести» меню «Текст» поинтереснее - он выводит текст в рабочей области окна (параметры, относящиеся к выводимому тексту, можно настраивать из вкладки «Текст в окне» диалогового окна «Дополнительные параметры»; см. рис. 3).


Рис. 3. Вкладка «Текст в окне».

ПРЕДУПРЕЖДЕНИЕ

Это как раз та ситуация, когда простого копирования кода из программы «Windows» в проект VC++ недостаточно. В данном случае мы использовали один собственный, т.е. не встроенный в Windows ресурс - меню, поэтому для корректной работы отдельно скомпилированной программы необходимо добавить в ее проект соответствующий RC-файл.

Листинг 2. RC-файл для включения в создаваемый проект VC++.
#define IDM_WINCLOSE	40006
#define IDM_WINTXT	40007

EXPERIMENTAL MENU 
BEGIN
    POPUP "&Окно"
    BEGIN
        MENUITEM "&Закрыть", IDM_WINCLOSE
    END
    POPUP "&Текст"
    BEGIN
        MENUITEM "&Вывести", IDM_WINTXT
    END
END

Задание

Закройте созданное окно. Снова найдите раскрывающийся список «Меню» и выберите на этот раз «Меню главной программы». Зарегистрируйте класс и создайте окно.

Меню нашего окна стало таким же, как меню самой программы «Windows». Выберите какой-нибудь пункт меню и щелкните на нем.

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

Фон окна (hbrBackground).

Фон окна можно выбрать на одноименной вкладке диалогового окна «Параметры структуры WNDCLASS» (рис. 4). Во всплывающих подсказках, как и ранее, отображаются описания соответствующих опций.


Рис. 4. Вкладка «Фон окна».

Задание

Выберите на вкладке «Фон окна» кнопку «NULL». Зарегистрируйте класс и создайте новое окно.

Уже сразу после создания окно выглядит необычно. Можно еще больше усилить этот эффект, если создать это окно на фоне других запущенных сложных приложений, например, CorelDraw! с рисунками.

Когда вы только что создали новое окно, перетащите правую сторону рамки окна влево. Пока все нормально, окно как окно, за исключением эффекта «прозрачности». Теперь перетащите рамку обратно вправо. На прежнем месте рамки остался «след». То же самое происходит при перетаскивании других сторон рамки.

Переместите само окно. Поэкспериментируйте с перемещением окна в разных направлениях, в том числе с выходом границы окна за пределы экрана. Попробуйте свернуть и развернуть окно.

Задание

Закройте окно и вызовите снова диалоговое окно «Параметры структуры WNDCLASS». Оставьте кисть «NULL» на вкладке «Фон окна», а на вкладке «Курсор, меню, функция окна» выберите меню «Экспериментальное». Зарегистрируйте класс и создайте новое окно.

Теперь в нашем «магическом» окне появилась строка меню. Выберите пункт «Вывести» меню «Текст» (необходимо позаботиться, чтобы фон окна в месте вывода текста был более-менее чистым, иначе текст окажется незаметным). Передвиньте правую сторону рамки окна влево так, чтобы она «срезала» часть текста. Верните ее на место. Проделайте это же с нижней стороной рамки. Сверните и снова восстановите окно. Обратите внимание, что строка заголовка и строка меню окна все время остаются нормальными, а все «приключения» относятся только к рабочей области окна.

Теперь вспомним, что происходило с текстом, который выводился по команде меню. Пока мы не сворачивали окно, не перекрывали его другим и не выводили область отображения текста за пределы экрана, он перемещался вместе с окном. Когда же мы проделывали одно из этих перечисленных действий, т.е. делали то, что требует перерисовки и соответствующего сообщения WM_PAINT, - текст исчезал. Поэтому практически каждое приложение, что-либо отображающее в рабочей области своего окна, должно это делать в процессе обработки сообщения WM_PAINT.

Задание

Закройте все ранее открытые окна. Проверьте, что в качестве фона окна класса выбрана кнопка «NULL». По команде «Дополнительно...» из меню «Параметры» вызовите диалоговое окно «Дополнительные параметры». Выберите вкладку «Текст в окне» (рис. 8), затем щелкните на кнопке «WM_PAINT» в группе «Событие». Можете также изменить по желанию текст для отображения в окне. Щелкните на кнопке «Принять». Создайте новое окно.

Теперь, как бы мы не перемещали наше окно, не изменяли его размеры, сворачивали, разворачивали - текст всегда остается на том же месте.

Перед приходом сообщения WM_PAINT окно получает сообщение WM_ERASEBKGND, позволяющее разделить собственно рисование и очистку фона окна. Обработчик по умолчанию (DefWindowProc) просто закрашивает клиентскую область окна кистью, указанной в классе окна. Если кисть не указана (hbrBackground равен NULL) или выбрана кисть HOLLOW_BRUSH или NULL_BRUSH, стандартный обработчик WM_ERASEBKGND не делает ничего, полностью полагаясь на программиста. Если программист не оправдывает надежды, проявляются те самые визуальные эффекты, которые мы только что наблюдали.

ПРИМЕЧАНИЕ

Самостоятельная обработка WM_ERASEBKGND – один из способов, позволяющих уменьшить мерцание при перерисовке. Отлично работает, если в обработчике WM_PAINT вы перерисовываете всю клиентскую область – в этом случае вам просто не нужна дополнительная очистка.

Задание

Закройте открытые окна. Выберите в качестве фона окна класса «BLACK_BRUSH». Оставьте обработку сообщения «WM_PAINT» на вкладке «Текст в окне» диалогового окна «Дополнительные параметры».

Мы видим полноценное окно, хотя и черное. Зато оно демонстрирует особенность вывода в окно: у выводимого текста есть свой, независимый от окна, фон (в данном случае, белый; понятно, что на белом фоне окна он совершенно незаметен).

Задание

Измените на вкладке «Текст в окне» фон текста на «Прозрачный». Остальные параметры оставьте теми же. Создайте новое окно.

Теперь мы никак не сможем доказать, что у нас в окне имеется текст!

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

Стиль класса (style).

Стиль класса можно выбрать на вкладке «Стиль и значок» диалогового окна «Параметры структуры WNDCLASS», которое вызывается при выборе пункта меню «Класс окна…» (рис. 1).

Стили класса могут комбинироваться с использованием поразрядного оператора ИЛИ (|). Возможна любая комбинация значений. Во всплывающих подсказках диалогового окна отображаются краткие сведения о соответствующем стиле; в таблице 1 приведены более полные описания для некоторых из них.

КонстантаЗначение
CS_BYTEALIGNCLIENTВыравнивает левую границу рабочей области окна по границе байта в видеопамяти для видеорежимов, использующих менее 8 битов на пиксель (что повышает производительность при использовании функции BitBlt()). В настоящее время устарел.
CS_BYTEALIGNWINDOWВыравнивает левую границу всего окна по границе байта в видеопамяти для видеорежимов, использующих менее 8 битов на пиксель. См. выше.
CS_CLASSDCВсе окна данного класса при рисовании в окне совместно используют единый контекст устройства, который создается для класса в целом.
CS_GLOBALCLASSПозволяет использовать класс окна, регистрируемый в функции инициализации DLL. При этом имя DLL должно быть указано в соответствующем ключе реестра.
CS_OWNDCКаждое окно данного класса при рисовании в окне использует собственный контекст устройства, недоступный для других окон.
CS_PARENTDCОкна данного класса при рисовании в окне используют контекст устройства своего родительского окна, что повышает производительность, а также позволяет рисовать в рабочей области своего родительского окна. Стандартные элементы управления Windows используют этот стиль.
Таблица 1. Дополнительные сведения о некоторых стилях класса окна.

Не все из возможных стилей можно наглядно продемонстрировать в действии. Рассмотрим наиболее употребительные из них.

Задание

На вкладке «Текст в окне» диалогового окна «Дополнительные параметры» (рис. 8) выберите событие «На щелчок мыши (WM_LBUTTONDOWN)». Щелкните на кнопке «Принять», затем создайте новое окно.

При щелчке в области нового окна в его рабочей области появляется текст. Подвигайте правую границу окна. Текст остается на месте, если только его не урезала граница окна. То же самое происходит при перемещениях нижней границы окна. Изображение в окне не перерисовывается.

Задание

Закройте предыдущее окно. Вызовите диалоговое окно «Параметры структуры WNDCLASS», на вкладке «Стиль и значок» пометьте кнопку «CS_HREDRAW». Зарегистрируйте класс и создайте новое окно.

Проделайте те же операции с текстом. Теперь при изменении горизонтального размера окна текст исчезает из-за перерисовывания окна. Поскольку вывод текста у нас осуществляется в ответ на сообщение WM_LBUTTONDOWN, а не WM_PAINT, окно закрашивается цветом фона, и текст стирается. Однако при изменении вертикальных размеров окна текст остается на месте.

Попробуйте изменить стиль класса окна на CS_VREDRAW. Теперь текст исчезает при изменении вертикальных размеров окна и сохраняется при изменении горизонтальных размеров. Если указать оба стиля (CS_HREDRAW | CS_VREDRAW), окно будет перерисовываться при любом изменении размеров окна.

Задание

Вызовите диалоговое окно «Дополнительные параметры», на вкладке «Текст в окне» выберите событие «На двойной щелчок (WM_LBUTTONDBLCLK)». Нажмите кнопку «Принять» и создайте новое окно.

Произведите двойной щелчок в рабочей области нового окна. Ничего не происходит? Для того, чтобы ваше окно могло получать сообщение о произведенном двойном щелчке, класс окна должен быть создан со стилем CS_DBLCLKS.

Из «наглядных» стилей можно попробовать еще один - CS_NOCLOSE, который создает «вечные» окна. Кнопка закрытия в правом верхнем углу окон данного класса недоступна, в системном меню отсутствует команда «Закрыть». Комбинация Alt + F4 также не срабатывает. Избавиться от него можно только закрыв саму программу «Windows».

Главная функция окна (lpfnWndProc).

lpfnWndProc должен содержать указатель на главную функцию окна. Несмотря на то, что данный член структуры WNDCLASS мы рассматриваем последним, он является, пожалуй, самым главным из всех, поскольку именно он определяет поведение окна, реакцию окна на поступающие сообщения и тем самым «одушевляет» окно. Главная функция окна является своего рода «главной диспетчерской», без которой ничего не происходит.

Задание

В программе «Windows» закройте все открытые ранее окна. В диалоговом окне «Параметры структуры WNDCLASS» выберите меню окна «Экспериментальное» и зарегистрируйте класс. На вкладке «Текст в окне» диалогового окна «Дополнительные параметры» выберите событие «На щелчок мыши (WM_LBUTTONDOWN)». Создайте новое окно.

Получившееся окно «умеет» выводить текст по команде от меню или в ответ на щелчок мыши. Текст можно «стирать», сворачивая и восстанавливая окно, или выводя область с тестом за пределы экрана и возвращая обратно (предварительно зафиксировав в выведенном состоянии). За «умения» окна отвечает как раз главная функция окна, внутри которой заложена обработка сообщений WM_COMMAND и WM_LBUTTONDOWN (соответствующий код мы можем увидеть в главной функции окна ExperimentalWndProc).

Задание

Закройте окно. На вкладке «Курсор, меню, функция окна» диалога «Параметры структуры WNDCLASS» выберите функцию окна «DefWindowProc». Зарегистрируйте класс и создайте окно.

Внешне новое окно совершенно не отличается от прежнего. Только вот оно перестало выполнять команды даже своего «родного» меню и перестало отвечать на щелчки мыши. Окно «разучилось» писать, потому что такая возможность не предусмотрена функцией DefWindowProc().

Функция DefWindowProc() - та самая, которой мы должны передавать все сообщения, посылаемые нашему окну, но не обрабатываемые его главной функцией. Именно этой функции мы обязаны тем, что все окна ведут себя, как окна - сворачиваются и разворачиваются, когда мы щелкаем на соответствующих кнопках, перемещаются, изменяют свои размеры, отображают название, меню - словом, выполняют все предусмотренные стандартные действия. Но нестандартные действия мы должны предусматривать сами и снабжать главную функцию нашего окна соответствующим кодом.

Задание

Закройте окно. Выберите из комбинированного списка функцию окна «Главной программы». Зарегистрируйте класс и создайте окно.

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

Эти особенности объясняются «устройством» главной функции главного окна приложения. Данная функция обрабатывает сообщение WM_CREATE, посылаемое при создании окна, и создает, в свою очередь, редактируемый элемент управления, занимающий всю рабочую область создаваемого окна и имеющий полосы прокрутки по краям. Именно это окно мы и видели. При закрытии же окна его главная функция получает сообщение WM_DESTROY, в ответ на которое функция «MainWndProc» программы «Windows» вызывает функцию PostQuitMessage(), прерывающую цикл обработки сообщений и завершающую тем самым приложение. Тогда как в главной функции «ExperimentalWndProc» обработка сообщения WM_DESTROY не предусмотрена, что позволяет приложению продолжать действовать и после закрытия окна.

ПРИМЕЧАНИЕ

Здесь есть сложность, связанная с тем, что программа «Windows» лишь эмулирует работу приложения, исходный код которого отображается в рабочей области главного окна. Программа «Windows» содержит как свою собственную главную функцию (MainWndProc), так и «экспериментальную» главную функцию для создаваемых окон (ExperimentalWndProc); и эта последняя как раз и не содержит обработки сообщения WM_DESTROY. В этом отношении отображаемый в окне код не совсем точен – он содержит «лишнюю» обработку сообщения WM_DESTROY, которой нет у той функции, которая фактически используется как главная функция для создаваемых окон. Это вынужденный шаг, т.к. в противном случае при компиляции сгенерированного в окне кода в виде отдельного приложения его невозможно будет завершить путем закрытия окна, что очень неудобно.

Задание

Закройте предыдущие окна, запустите вновь программу «Windows». На вкладке «Курсор, меню, функция окна» выберите и функцию, и меню программы «Windows». Зарегистрируйте класс и создайте окно.

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

Эксперименты с «чужой» главной процедурой окна – еще один случай, когда копирования кода из главного окна приложения в шаблон и последующего компилирования недостаточно для получения тех эффектов, которые мы могли в данном случае наблюдать. Происходит это потому, что создаваемые «изнутри» нашего приложения окна имеют возможность воспользоваться ресурсами данной программы (в частности, соответствующими шаблонами диалогов), а также кодом других функций программы, чего будут лишены окна отдельно скомпилированного приложения.

Функция CreateWindowEx()

Напомним определение функции CreateWindowEx() для создания окна (см. листинг 3).

Листинг 3.
HWND CreateWindowEx(
  DWORD dwExStyle,      // расширенный стиль окна
  LPCTSTR lpClassName,  // указатель на имя зарегистрированного класса
  LPCTSTR lpWindowName, // указатель на имя окна
  DWORD dwStyle,        // стиль окна
  int x,                // горизонтальное положение окна
  int y,                // вертикальное положение окна
  int nWidth,           // ширина окна
  int nHeight,          // высота окна
  HWND hWndParent,      // дескриптор родительского окна
  HMENU hMenu,          // дескриптор меню или идентификатор дочернего окна
  HINSTANCE hInstance,  // дескриптор экземпляра приложения
  LPVOID lpParam        // указатель на дополнительные данные окна
);

Параметры дополнительных данных окна (lpParam) и экземпляра приложения (hInstance) в программе «Windows» не изменяются. Остальные параметры можно настраивать через диалоговое окно «Параметры функции CreateWindowEx()»

Заголовок окна (lpWindowName).

Заголовок окна можно задать в поле с аналогичным названием на вкладке «Прочие» диалогового окна «Параметры функции CreateWindowEx()», которое вызывается при выборе пункта «Окно…» меню «Параметры» программы «Windows» (рис. 5).


Рис. 5. Вкладка «Прочие».

Положение окна (x и y).

Эти параметры определяют начальное положение левого верхнего угла окна относительно экрана для перекрывающихся и всплывающих окон, относительно левого верхнего угла рабочей области родительского окна - для дочерних окон.

Если x равен CW_USEDEFAULT, система устанавливает положение для левого верхнего угла окна по умолчанию и игнорирует параметр y. Это значение относится только к перекрывающимся окнам; если он определен для всплывающих (со стилем WS_POPUP) или дочерних окон, x и y устанавливаются в 0.

Задание

Выберите вкладку «Прочие» диалога «Параметры функции CreateWindowEx()». В группе «Расположение окна» введите следующие значения: слева - (-100), сверху - (-100). Щелкните на кнопке «Принять». Создайте новое окно.

Как видим, можно задать даже отрицательные координаты расположения окна, и оно будет выведено соответствующим образом. Правда, переместить его с помощью мыши не удастся, поэтому, чтобы вернуть окно в благопристойное положение, проделайте следующее: нажмите клавиши Alt + пробел, в появившемся системном меню выберите «Переместить», затем переместите окно с помощью клавиш перемещения курсора в соответствующее положение.

Размеры окна (nWidth и nHeight).

Определяют ширину (nWidth) и высоту (nHeight) окна в единицах устройства. Если nWidth равно CW_USEDEFAULT, то ширина и высота перекрывающегося окна устанавливаются по умолчанию, параметр nHeight при этом игнорируется. Если CW_USEDEFAULT использовано для всплывающих (WS_POPUP) и дочерних окон, параметры nWidth и nHeight устанавливаются в 0 (окно при этом не отображается).

Меню окна (hMenu).

В зависимости от стиля окна, обозначает либо дескриптор меню, либо идентификатор дочернего окна. Для перекрывающихся или всплывающих окон hMenu обозначает меню, которое должно использоваться вместе с данным окном; это может быть NULL, если используется меню класса. Для дочерних окон hMenu определяет идентификатор дочернего окна - целое число, используемое элементом управления диалогового окна для извещения родительского окна о сообщениях. Идентификатор дочернего окна определяет само приложение; это должно быть уникальное для всех дочерних окон для данного родительского окна.

Задание

Откройте вкладку «Прочие» диалогового окна «Параметры функции CreateWindowEx()». Из раскрывающегося списка «Меню окна» выберите «Меню главной программы». Щелкните на кнопке «Принять», затем создайте новое окно.

Убедитесь, что меню раскрывается, однако, соответствующие команды не исполняются. Закройте окно и вызовите диалоговое окно «Параметры структуры WNDCLASS». На вкладке «Курсор, меню, функция окна» выберите меню «Собственное» и зарегистрируйте класс. Создайте новое окно.

Родительское окно (hWndParent).

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

Задание

На вкладке «Прочие» выберите следующие параметры функции окна: слева - 100, сверху - 100, ширина - 500, высота - 400. Восстановите главное окно программы и создайте новое окно.

Переместите новое окно так, чтобы оно занимало положение «каскадом» с главным окном. Пощелкайте на этих окнах и понаблюдайте, как окна перекрывают друг друга при активации.

Закройте настраиваемое окно. На вкладке «Прочие» выберите в качестве родительского главное окно программы. Создайте окно.

Обратите внимание, что окно выводится в экранной системе координат. Пощелкайте на двух окнах: даже при потере фокуса настраиваемое окно оказывается перед главным. Кроме того, обратите внимание на отсутствие соответствующей настраиваемому окну кнопки на панели задач. При сворачивании настраиваемого окна оно оказывается в левом нижнем углу экрана; при сворачивании главного окна вообще исчезает. При данном типе отношений говорят, что одно окно (в данном случае главное) владеет другим (здесь - «настраиваемым»). Это происходит в тех случаях, если при создании окна указан дескриптор родительского окна, но не установлен флаг окна WS_CHILD.

Закройте настраиваемое окно. Откройте вкладку «Стили» диалога «Параметры функции CreateWindowEx()». Не снимая флага WS_OVERLAPPEDWINDOW, установите флаг WS_CHILD. Создайте окно.

Первое окно создать не удастся. Еще раз выберите команду «Создать окно». Однако, и появившееся на этот раз окно является лишь фантомом, лишь следом окна. Дело в том, что программа «Windows» уже имеет одно дочернее окно - это редактируемый элемент управления, занимающий всю рабочую область главного окна. Создаваемое нами дочернее (со стилем WS_CHILD) окно оказывается вторым, причем эти два дочерних окна перекрываются и начинают рисовать друг на друге. Чтобы этого не происходило, для перекрывающихся дочерних окон необходимо указывать стиль WS_CLIPSIBLINGS (см. раздел «Стиль окна»). Однако в данном случае не поможет даже это, поскольку окно редактирования создавалось без этого стиля.

Закройте настраиваемое окно. На вкладке «Прочие» установите в качестве родительского «Редактируемое окно». Создайте новое окно.

Теперь дочернее окно можно перемещать. Обратите внимание, в каком месте появляется новое окно - координаты для вывода дочернего окна отсчитываются от левого верхнего угла рабочей области родительского окна, а не экрана. Дочернее окно не может выходить за пределы клиентской области родительского - выходящие части «обрезаются». При сворачивании родителя дочернее окно исчезает; при закрытии родителя дочернее окно также закрывается.

Имя класса окна (lpClassName).

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

ПРЕДУПРЕЖДЕНИЕ

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

Задание

Выберите следующие параметры класса: значок - IDI_ERROR, курсор - IDC_WAIT, меню и функция окна – «Экспериментальные», фон окна - BLACK_BRUSH. Зарегистрируйте класс. На вкладке «Прочие» диалога «Параметры функции CreateWindowEx()» выберите класс окна «Главной программы». На вкладке «Текст в окне» диалога «Дополнительные параметры» выберите сообщение «На щелчок мыши (WM_LBUTTONDOWN)». Создайте окно.

Такой странный набор параметров класса окна был выбран именно из-за его странности, благодаря чему окно данного класса сразу бросается в глаза. Обратите внимание, что ни один из выбранных нами параметров класса не действует. Это и понятно, поскольку выбранные нами параметры относятся к классу окна «ExperimentalClass», а мы выбрали класс главного окна программы. Щелчок мыши не действует, поскольку соответствующий код по выводу текста находится в функции ExperimentalWndProc(), а класс окна программы «Windows» определяет в качестве главной функции окна MainWndProc().

Из второго окна вызовите диалог «Параметры функции CreateWindowEx()» и выберите меню «Экспериментальное». Из второго же окна создайте еще одно окно.

Новое (третье) окно можно было бы создать и из первого окна; мы создаем его из второго окна, чтобы убедиться, что второе окно обладает той же функциональностью, что и первое, поскольку у них общий класс окна и, соответственно, одна и та же главная функция окна. Третье окно содержит другое, «экспериментальное» меню, которое, однако, не действует, поскольку и это третье окно относится к тому же классу, что и первые два, и соответственно, его главной функцией также является MainWndProc(), в которой отсутствует код обработки сообщений от «экспериментального» меню.

Вернитесь ко второму окну (ни одно из окон не закрывайте!). Из второго окна вызовите диалог «Параметры функции CreateWindowEx()» и выберите класс окна «ExperimentalClass». Из второго же окна создайте новое (четвертое по счету!) окно.

Также, как и третье, четвертое окно можно было бы создать и из первого окна, свернув второе и третье. Но мы не можем проделать то же из третьего окна, поскольку оно содержит «экспериментальное» меню, к тому же не действующее. А вот «экспериментальное» меню четвертого окна работает, также, как «работает» и щелчок мыши – в отличие от первых трех, четвертое окно относится к классу «ExperimentalClass», который мы зарегистрировали в самом начале; этот класс в качестве ссылки на главную функцию окна содержит адрес «ExperimentalWndProc», в которой предусмотрена обработка команд от «экспериментального» меню. Опять же в отличие от прежних трех, четвертое окно можно без ущерба для главного окна приложения закрыть. Закрытие второго или третьего окна приводит к закрытию всех остальных.

Стиль окна (dwStyle).

Основной стиль окна можно задать на вкладке «Стили» диалогового окна «Параметры функции CreateWindowEx()» (рис. 6).


Рис. 6. Вкладка «Стили».

Этот параметр может быть комбинацией стилей, приведенных на вкладке «Стили», и дополнительных стилей элементов управления, которые здесь не рассматриваются. Как и раньше, краткие сведения о соответствующем стиле отображаются во всплывающих подсказках, а в таблице 2 приведены дополнительные сведения для некоторых стилей.

СтильЗначение
WS_CAPTIONОкно с заголовком (включает в себя также стиль WS_BORDER).
WS_CLIPCHILDRENИсключает область дочернего окна при рисовании в родительском окне. Этот стиль используется при создании родительского окна.
WS_CLIPSIBLINGSИсключение областей дочерних окон друг относительно друга, т.е. при получении дочерним окном сообщения WM_PAINT стиль WS_CLIPSIBLINGS исключает области всех других дочерних окон из зоны рисования. Если стиль WS_CLIPSIBLINGS не указан, а дочерние окна перекрываются, при рисовании в области пользователя дочернего окна возможен заход в область пользователя соседнего дочернего окна.
WS_DISABLEDСоздает окно, доступ к которому запрещен (окно, которое не может получать ввод от пользователя).
WS_GROUPОпределяет первый управляющий элемент в группе, причем в группу входит данный элемент и все последующие до следующего управляющего элемента со стилем WS_GROUP. Обычно первый элемент в группе имеет также стиль WS_TABSTOP, чтобы пользователь мог перемещаться от одной группы к другой. Внутри группы пользователь может перемещаться от одного элемента управления к другому с использованием клавиш перемещения курсора.
WS_MAXIMIZEBOX, WS_MINIMIZEBOXСоздает окно с кнопкой максимизации или минимизации соответственно. Должен быть указан также стиль WS_SYSMENU. Не может быть использован со стилем WS_EX_CONTEXTHELP.
WS_OVERLAPPED, WS_TILEDПерекрывающееся окно, имеющее заголовок и обрамление.
WS_OVERLAPPEDWINDOW, WS_TILEDWINDOWСоздает перекрывающееся окно с заголовком, системным меню, перемещаемым обрамлением и кнопками минимизации и максимизации (комбинация стилей WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX и WS_MAXIMIZEBOX).
WS_POPUPWINDOWСоздает всплывающее окно с обрамлением и системным меню (комбинация стилей WS_BORDER, WS_POPUP и WS_SYSMENU). Чтобы меню окна было видимым, необходимо комбинировать данный стиль со стилем WS_CAPTION.
WS_SYSMENUСоздает окно, имеющее системное меню в заголовке. Должен быть также указан стиль WS_CAPTION.
WS_TABSTOPОпределяет элемент управления, на который можно переместиться нажатием клавиши <Tab>. Нажатие данной клавиши перемещает фокус ввода на следующий элемент управления, имеющий стиль WS_TABSTOP.
Таблица 2. Дополнительные сведения о некоторых стилях окна.

Приступим к «конструированию» окна из стилей.

Задание

На вкладке «Стили» диалогового окна «Параметры функции CreateWindowEx()» снимите флажок со стиля WS_OVERLAPPEDWINDOW и выберите стиль WS_POPUP. Перейдите на вкладку «Прочие» и введите координаты окна: слева - 100, сверху - 100, ширина - 500, высота - 400. Щелкните на клавише «Принять», затем создайте окно.

На белом фоне окно может быть не видно, хотя оно присутствует. Если мы посмотрим на панель задач, то увидим там кнопку с названием «Настраиваемое ...». Она относится к нашему окну.

Закройте окно, нажав Alt + F4. На вкладке «Прочие» выберите меню окна «Экспериментальное». Нажмите клавишу «Принять» и создайте новое окно.

У нашего окна появилось меню. Причем оно даже действует - можно выводить текст и закрыть окно.

Чтобы сделать наличие окна более ощутимым, можно изменить фон окна.

Закройте предыдущее окно. В поле «Меню окна» выберите NULL. Вызовите диалоговое окно «Параметры структуры WNDCLASS» и на вкладке «Фон окна» отметьте кнопку «LTGRAY_BRUSH». Зарегистрируйте класс и создайте окно.

Вот теперь всем видно, что окно действительно есть. Оно даже напоминает нам кое-что, хотя чего-то, кажется, и не хватает...

Закройте окно. Не снимая флажка со стиля WS_POPUP, поставьте еще один рядом со стилем WS_DLGFRAME. Нажмите «Принять» и создайте окно.

Ну конечно! Снабдив окно элементами управления по своему вкусу, получим диалоговое окно.

Вернемся к нашему первому окну. На самом деле, стиль WS_POPUP стоит того, чтобы с ним поэкспериментировать, он позволяет «почувствовать» сущность окна Windows.

Закройте ранее открытые окна. Установите стиль окна WS_POPUP. В диалоговом окне «Параметры структуры WNDCLASS» выберите в качестве фона окна NULL и зарегистрируйте класс. На вкладке «Текст в окне» диалогового окна «Дополнительные параметры» выберите событие «На щелчок мыши (WM_LBUTTONDOWN)», фон текста - обычный. Создайте окно.

Теперь при щелчке левой клавишей мыши на экране в самом неожиданном месте появляется текст. (Вы можете изменить место его появления, задав соответствующие параметры на вкладке «Текст в окне»). Если затем щелкнуть где-нибудь за пределами этого невидимого окна, текст исчезнет, поскольку само окно уходит «на задний план». После этого щелчок на прежнем месте уже не вызывает появления текста. Однако, вы можете активировать это невидимое окно, щелкнув на кнопке «Настраиваемое ...» (если название окна не было изменено) на панели задач. Теперь текст появится снова. Чтобы закрыть это окно, придется воспользоваться сочетанием Alt + F4.

Закройте окно. Задайте на вкладке «Прочие» следующие размеры окна: слева - 0, сверху - 0, ширина - значение установленного вами разрешения экрана по горизонтали (например, 1024), высота - значение разрешения вашего экрана по вертикали (например, 768). Примите эти значения и создайте окно.

Где бы теперь ни щелкать, появляется наш текст - причем он может быть в самых разных местах - даже поверх заголовков других окон или поверх панели задач. А после щелчка...

Нет, система не зависла. Хотя попытки перейти к другому окну, щелкая на соответствующей кнопке панели задач, вызвать системное меню и даже закрыть окно мышью наводят именно к такой мысли. Просто наше невидимое окно закрыло собой весь экран, и все, что мы видим на нем, - не более, чем мираж. Это не «настоящие другие» окна (и даже системная панель задач), это всего лишь их изображение в нашем «окне без фона». Чтобы этот мираж рассеялся, нажмите Alt + F4.

Закрыв предыдущее окно, установите фон текста «Прозрачный», выбрав вкладку «Текст в окне». Зафиксируйте этот параметр и создайте окно.

Теперь наше приложение с подобным окном вполне может сойти за какой-нибудь вирус, стремительно разрушающий систему. Чтобы усилить это впечатление, можно слегка переделать фрагмент «case WM_LBUTTONDOWN:» главной процедуры окна, передавая текущие координаты мыши в функцию «TextOut()».

Однако, пора двинуться дальше в нашем стремлении к «идеальному окну».

Измените параметры класса окна, восстановив фон «WHITE_BRUSH». Установите стили окна WS_POPUP и WS_BORDER, расположение окна: слева - 100, сверху - 100, ширина - 500, высота - 400. Создайте окно.

Именно такое окно мы видим при загрузке Visual C++ 6. Внешне похожую картину дает стиль WS_POPUPWINDOW (без других стилей), но на самом деле, он является объединением стилей (WS_POPUP | WS_BORDER | WS_SYSMENU), что мы увидим позже.

Добавьте к установленным ранее стилям WS_CAPTION. Создайте новое окно.

Появление строки заголовка не ограничивается лишь выведением самого заголовка окна, который раньше появлялся только на кнопке в панели задач. Рамка окна изменилась и стала настоящим обрамлением, хотя изменять размеры окна еще нельзя. Зато теперь можно перемещать само окно, зацепляя его мышью за загривок (прошу прощения, за заголовок).

Получившаяся комбинация стилей имеет собственное наименование - WS_OVERLAPPED (другое его название - WS_TILED). Попробуйте снять установленные ранее стили и установите только WS_OVERLAPPED (или WS_TILED). Мы получим прежнее окно.

Добавьте к прежним стилям стиль WS_SYSMENU и создайте новое окно.

Наконец-то в нашем окне появляется его «законный» значок. Щелчок на нем открывает системное меню, одинаковое для всех окон; однако не все пункты этого меню доступны. Одновременно в правом конце строки заголовка появляется кнопка закрытия окна. (Если установить стиль класса окна CS_NOCLOSE, она будет недоступна; не будет соответствующей команды и в системном меню).

В окне со стилем WS_POPUPWINDOW, о котором мы упомянули ранее, системного меню не видно (хотя оно и определено). Сейчас мы убедимся в этом.

Закройте предыдущие окна. Сбросьте все стили и установите WS_POPUPWINDOW. Создайте новое окно.

Поскольку строка заголовка вместе со значком отсутствуют, доступ к системному меню можно получить только с помощью клавиатуры. Нажмите Alt + пробел. В появившемся меню доступны всего две команды - «Переместить» и «Закрыть». Выберите команду «Переместить». Курсор примет форму четырехнаправленной стрелки. Чтобы переместить окно, необходимо вначале нажать какую-нибудь из клавиш перемещения курсора, после чего форма указателя изменится на обычную стрелку. Теперь окно будет перемещаться вместе с мышью; чтобы зафиксировать новое положение окна, щелкните левой клавишей. Перемещать окно можно с использованием клавиш передвижения курсора, для фиксирования нового положения нажмите на клавишу «Enter».

Добавьте стиль WS_CAPTION и создайте новое окно.

Теперь мы получаем доступ к системному меню, щелкая на значке окна. Двинемся дальше в конструировании окон.

Добавьте к предыдущим двум стилям стиль WS_THICKFRAME и создайте новое окно (аналогичного результата можно добиться, добавив этот стиль к комбинации стилей (WS_OVERLAPPED | WS_SYSMENU).

Наше окно может теперь менять свои размеры. Одновременно в системном меню стала доступной команда «Размер». Стиль WS_THICKFRAME равнозначен стилю WS_SIZEBOX.

Добавьте к предыдущим стиль WS_MINIMIZEBOX и создайте новое окно.

Наконец-то наше окно получает полный комплект кнопок окна. Правда, кнопка разворачивания недоступна, как и соответствующий пункт меню. Как вы уже догадались, за доступность этого пункта отвечает стиль WS_MAXIMIZEBOX. Эти два новых стиля работают только в том случае, если окно имеет системное меню (т.е. определено со стилем WS_SYSMENU). Получившаяся комбинация стилей нашего «полноценного» окна объединяется под названием WS_OVERLAPPEDWINDOW (не путать с WS_OVERLAPPED!) или WS_TILEDWINDOW (соответственно не путать с WS_TILED).

Итак, сконструировав «совершенное» окно, мы можем теперь позаботиться о его «роскоши» - дополнительных элементах. С одним из них мы уже знакомы - это меню. Другой вид - полосы прокрутки, которые мы можем определить прямо в стилях окна.

Закройте все окна. Создайте новое окно со стилями (WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL).

Теперь наше окно будет получать соответствующие сообщения WM_HSCROLL и WM_VSROLL, ответ на которые будет определять поведение наших полос прокрутки.

Остальные стили касаются отображения окна, и результат здесь зависит от их взаимодействия с функцией ShowWindow(), которую мы рассмотрим в разделе, посвященном этой функции.

Расширенный стиль окна (dwExStyle).

Расширенные стили окна можно задать на одноименной вкладке диалогового окна «Параметры функции CreateWindowEx()» (рис. 7).


Рис. 7. Вкладка «Расширенные стили».

Этот параметр может принимать значения, указанные на вкладке «Расширенные стили». Дополнительные сведения для некоторых из них приведены в таблице 3.

СтильЗначение
WS_EX_LEFT, WS_EX_RIGHTОкно имеет общий стиль «левостороннего» (по умолчанию) или «правостороннего» выравнивания соответственно. «Правосторонний» стиль действует лишь, когда язык оболочки с обратным порядком чтения (справа налево).
WS_EX_RIGHTSCROLLBAR, WS_EX_LEFTSCROLLBARВертикальная полоса прокрутки (при ее наличии) размещается в правой (по умолчанию) или левой части рабочей области окна соответственно. Слева полоса прокрутки может размещаться, лишь если язык оболочки с порядком чтения справа налево.
WS_EX_LTRREADING, WS_EX_RTLREADINGТекст окна отображается слева направо (по умолчанию) или справа налево соответственно. Последний стиль действует лишь в случае, если язык оболочки с порядком чтения справа налево.
WS_EX_TOPMOSTОкно, созданное с этим стилем, остается поверх всех других окон без данного стиля, даже если фокус ввода принадлежит другому окну.
Таблица 3. Дополнительные сведения о некоторых расширенных стилях окна.

Рассмотрим лишь некоторые из этих стилей (с остальными поэкспериментируйте самостоятельно).

Задание

На вкладке «Стили» выберите WS_OVERLAPPED | WS_SYSMENU; на вкладке «Расширенные стили» - WS_EX_CONTEXTHELP; установите размер окна по умолчанию (CW_USEDEFAULT). Создайте новое окно.

Щелкните на кнопке с вопросом рядом с кнопкой закрытия окна. Курсор изменяет форму на стрелку с вопросом и сохраняет ее в пределах данного окна до щелчка левой или правой клавишей мыши. Понаблюдайте, как меняется форма курсора при выходе за пределы окна.

Выберите стиль WS_OVERLAPPEDWINDOW, расширенный стиль WS_EX_TOPMOST. Создайте новое окно.

Попробуйте щелкнуть мышью за пределами данного окна. Запустите несколько разных приложений и попереключайтесь между ними. Теперь вы знаете, как создается окно справки «все время наверху». Не изменяя настроек, создайте еще одно окно. Между несколькими окнами со стилем WS_EX_TOPMOST можно переключаться обычным образом (зато все остальные окна без данного стиля будут все время внизу).

Закройте все предыдущие окна. Выберите следующие настройки: стиль WS_OVERLAPPEDWINDOW, расширенный стиль WS_EX_TOOLWINDOW. Создайте окно.

Хотя стиль нашего окна предполагает наличие значка и кнопок свертывания и разворачивания окна, их нет благодаря расширенному стилю. Обратите внимание на мелкий шрифт. Системное меню, однако, доступно при нажатии клавиш Alt + пробел, а также при щелчке правой кнопкой мыши на строке заголовка.

Нажмите Alt + Tab. На панели задач имеется только значок программы «Windows».

Не снимая ранее установленных стилей, отметьте еще один расширенный стиль - WS_EX_APPWINDOW. Создайте новое окно.

Нажмите теперь Alt + Tab. Как видим, стиль WS_EX_APPWINDOW в принудительном порядке помещает кнопку окна на панель задач, если оно ранее там не находилось.

Отображение окна

Значение, передаваемое функции ShowWindow() для отображения или изменения состояния окна, можно выбрать на вкладке «Отображение окна» диалогового окна «Дополнительные параметры» (рис. 8), которое вызывается при выборе пункта «Дополнительно…» меню «Параметры». Во всплывающих подсказках содержатся краткие описания; в таблице 4 приведены более развернутые описания для некоторых из них.


Рис. 8. Вкладка «Отображение окна».

ФлагЗначение
SW_RESTOREАктивизирует и отображает окно. Если окно развернуто или свернуто, система восстанавливает его первоначальные размеры и положение. Приложение должно указать это значение при восстановлении свернутого окна.
SW_SHOWDEFAULTУстанавливает состояние отображения в соответствии со значением SW_, определенным в структуре STARTUPINFO, переданной функции CreateProcess() программой, запустившей данную.
SW_SHOWMINNOACTIVEОтображает окно в свернутом виде. Если окно при этом было активно, оно остается активным.
SW_SHOWNAОтображает окно в его текущем состоянии. Активное окно остается активным.
SW_SHOWNOACTIVATEОтображает окно с размерами и положением, которое было в последний раз. Активное окно остается активным.
SW_SHOWNORMALАктивизирует и отображает окно. Если окно свернуто или развернуто, система восстанавливает его первоначальные размеры и положение, которые были указаны при запуске приложения в STARTUPINFO.
Таблица 4. Дополнительные сведения для некоторых значений параметра nCmdShow функции ShowWindow().

Задание

На вкладке «Отображение окна» диалога «Дополнительные параметры» выберите SW_SHOW. На вкладке «Стили» диалога «Параметры функции CreateWindowEx()» выберите стили (WS_OVERLAPPEDWINDOW | WS_MAXIMIZE). Создайте окно.

Новое окно оказывается развернутым во весь экран. При указании стиля WS_MINIMIZE или WS_ICONIC оно появится в свернутом состоянии. Флаг функции ShowWindow() иной, чем SW_SHOW, приводит к игнорированию указанных в параметре style функции CreateWindowEx() флагов отображения окна.

Заключение

В свое время, экспериментируя с этой учебной программой, я выяснил для себя множество интересных вещей. С большой долей вероятности можно сказать, что практически любой, даже достаточно опытный, программист может при помощи подобных экспериментов открыть для себя что-то новое. Различных параметров и возможностей обычно слишком много, а редактировать исходные коды специальных «учебных» проектов, даже очень простых, становится весьма утомительно, чтобы охватить таким образом всё. Данная же учебная программа позволяет сэкономить львиную долю усилий, уходящих на рутинные и совершенно не относящиеся к существу дела действия.

В то же время эту программу можно использовать, как первый шаг для быстрого создания «болванки» исходного приложения, с которым можно проводить уже более сложные эксперименты с использованием среды разработки вроде VC++. С другой стороны, наличие встроенных «рефлексивных» возможностей, наподобие использования главной функции окна и класса окна основного приложения для создания новых окон, позволяет придумывать новые изощренные эксперименты, способные натолкнуть на осмысление тонких нюансов работы с окнами. Все решает лишь ваша фантазия – экспериментируйте!


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.