DefWindowProc).
1.8. Отображение формы поверх других окон
Иногда вам может пригодиться возможность отображения формы поверх всех окон. За примером далеко ходить не надо: посмотрите на окно Диспетчера задач Windows. А теперь вспомните, терялось ли хоть раз окно Свойства: Экран среди других открытых окон. Это происходит из-за того, что оно перекрывается другими окнами и при этом не имеет никакого значка на Панели задач (правда, это окно все же можно найти с помощью Диспетчера задач).
Из сказанного выше можно заключить, что как минимум в двух случаях отображение поверх других окон может пригодиться: для важных окон приложения (например, окно ввода пароля) и/или в случае, если значок приложения не выводится на Панели задач (как скрыть значок, было рассказано выше).
После небольшого отступления рассмотрим способы, позволяющие задать положение формы так, чтобы другие окна не могли ее закрыть.
Первый способ прост «до безобразия»: достаточно задать свойству FormStyle в окне Object Inspector значение f sStayOnTo. Результат этого действия показан на рис. 1.19 (обратите внимание, что форма закрывает Панель задач, которая по умолчанию также отображается поверх всех окон).
Рис. 1.19. Форма, отображаемая поверх других окон
Второй способ пригодится, если форма отображается постоянно как обычно, однако в определенные моменты времени требует к себе пристального внимания, для чего и помещается наверх. Способ основан на использовании API-функции SetWindowPos, которая кроме позиции и размера окна может еще устанавливать порядок рисования окна (Z- order).
Примечание
Под Z-order подразумевается порядок следования окон вдоль оси Z, направленной перпендикулярно экрану (оси X и Улежат в плоскости экрана).
Вызов функции SetWindowPos для помещения окна наверх выглядит следующим образом (Handle – дескриптор нужного окна):
SetWindowPos (Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE)
В таком случае окно может быть закрыто другим окном, также отображающимся поверх других (например, Диспетчером задач).
Чтобы восстановить нормальное положение (порядок рисования) окна, можно вызвать функцию SetWindowPos со следующим набором параметров:
SetWindowPos (Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE)
После этого другие, неотображаемые поверх остальных, окна могут снова перекрывать нашу форму.
Глава 2 Уменьшение размера ЕХЕ-файла. Использование Windows API
• Источник лишних килобайт
• Создание окна вручную
• Окно с элементами управления
• Стандартные диалоговые окна Windows
• Установка шрифта элементов управления
Не секрет, что размер скомпилированного ЕХЕ-файла Delphi часто значительно превосходит размер программ, написанных с использованием сред разработки от Microsoft (например, Visual C++, Visual Basic).
Примечание
Здесь и далее имеются в виду приложения с оконным интерфейсом (не консольные).
При разработке крупных проектов этот факт абсолютно не смущает. Однако что же делать, если программисту на Delphi нужно написать программу, занимающую как можно меньше места (например, инсталлятор) или загружающуюся за минимальное время (например, сервисную программу). Конечно, такое приложение можно написать на C++, но что делать, если осваивать новый язык программирования нет времени?
В этой главе будут рассмотрены два способа уменьшения размера ЕХЕ-файла: отказ от библиотеки Borland за счет прямого использования Windows API и разбиение приложения на несколько DLL. Первый способ позволяет реально уменьшить размер приложения. Однако написание Delphi-приложения (да еще и с оконным интерфейсом) с использованием только API-функций является задачей весьма трудоемкой, хотя и интересной, да к тому же и экзотичной. Второй же способ не уменьшает размера проекта в целом, но может сэкономить время запуска приложения.
Вначале небольшое отступление. Итак, операционная система (в нашем случае это Windows) предоставляет интерфейс для программирования внутри себя – набор функций, заключенных в нескольких системных библиотеках, называемый Windows API (Windows Application Programming Interface – интерфейс программирования Windows-приложений). Любой проект под Windows на любом языке программирования в конечном счете сводится именно к приложению, использующему функции Windows API. Только использование этих самых функций может быть как явным, так и скрытым за использованием библиотек, поставляемых вместе со средой программирования.
И еще один момент. В тексте постоянно говорится о Windows API, а не просто API. Это потому, что само понятие Application Programming Interface применяется ко многим системам, а не только к ОС, и уж тем более не только к Windows. Вот несколько примеров: UNIX API, Linux API, Oracle API (интерфейс для работы с СУБД Oracle) и т. д.
Примечание
В книге описаны только те возможности Window API, которые непосред – ственно используются в примерах. Полное описание Windows API является слишком большой задачей, для которой не хватит и книги. Если вам захочется изучить или хотя бы узнать больше о Windows API, то можно обратиться к специализированным изданиям по этой теме. Однако никакое издание не заменит MSDN (огромная справочная система от Micr osoft для Visual Studio).
Теперь выясним, за счет чего разрастается ЕХЕ-файл приложения при использовании среды программирования Delphi.
2.1. Источник лишних килобайт
Для начала создадим новый проект Windows-приложения (Pro j ectl. exe). По умолчанию оно создает и показывает одну пустую форму (объявлена в модуле Unitl. pas). Ничего менять не будем, просто скомпилируем и посмотрим размер ЕХЕ-файла. Больше 300 Кбайт – не многовато ли для такого простого приложения?
Кстати, простейшее оконное приложение, написанное на Visual C++ 6.0 (в Release-конфигурации, то есть без отладочной информации в ЕХЕ-файле) без использования MFC, имеет размер 28 Кбайт, с использованием библиотеки MFC (правда, окно диалоговое) – 20 Кбайт. Простейшее оконное приложение на Visual Basic 6.0 занимает всего 16 Кбайт.
Из-за чего такая разница? Посмотрим, какие библиотеки используются приложениями, написанными на этих языках программирования. Это можно сделать, например, с помощью программы Dependency Walker, входящей в комплект Microsoft Visual Studio (рис. 2.1).
Рис. 2.1. Библиотеки, используемые приложениями
Как видим, приложение на Delphi (правый верхний угол окна на рис. 2.1) использует приличный набор функци й, помещенных в стандартные библиотеки операционной системы Windows. Кроме библиотек операционной системы, приложение на Delphi ничего не использует.
Приложение WinAPI. ехе (левое верхнее окно на рис. 2.1) является примером чистого Windows API приложения в том смысле, что в нем не задействованы библиотеки-оболочки над API-функциями, каким-либо образом облегчающие программирование. Собственно, столько реально и «весит» простейшее оконное приложение.
С приложением MFC. ехе уже интереснее: размер самого ЕХЕ-файла уменьшился за счет того, что часть кода работы с API- функциями переместилась в библиотеки. С приложением на Visual Basic (правое нижнее окно) еще интереснее – оно фактически представляет собой вызовы функций одной библиотеки, в которой и реализована вся поддержка программирования на этом языке (при детальном рассмотрении этой библиотеки в ней можно найти объявления встроенных функций Visual Basic).
К чему это все? А к тому, что приложения на других языках программирования (в данном случае речь идет о продуктах Microsoft) совсем не менее «тяжеловесны», чем приложения, написанные на Borland Delphi, если при их написании программист пользуется не только API-функциями. Особенно примечателен в этом случае пример исполняемого файла Visual Basic, который хотя и имеет малый размер, но требует наличия библиотеки, размер которой около 1,32 Мбайт. Программа на Visual C++ с использованием, например, MFC, в которой реализованы классы оболочки над функциями Windows API (правда, не только они), требуетналичия нескольких DLL. Для Microsoft это не проблема, так как операционная система Windows выпускается именно этой компанией, а следовательно, обеспечить переносимость (здесь – работоспособность без установки) приложений, написанных с использованием ее же сред разработки, очень просто: достаточно добавить нужные библиотеки в состав ОС.
Что же в таком случае осталось сделать Borland? Дабы не лишать программиста возможности пользоваться библиотеками с реализацией самых полезных классов (VCL и не только), код с реализацией этих самых классов приходится компоновать