Rambler's Top100


Виртуальный клуб начинающих программистов на Delphi


Заводь
Мелководье
Сокровищница
Рифы
Течения
Архивный грот
Дальние земли
Жемчужница
Ловцы жемчуга
Почтовый грот
Дельфинарий
Карта бухты

Rambler's Top100


Mastak.ru - качественный хостинг на двух континентах

The List of Russian Web Servers WebList.Ru

Безопасность прежде всего!
Установка параметров компилятора для повышения безопасности.
Упрощение логики.
Давайте предпочтем безопасность!
Программирование в хорошей форме.
План программы.
Произведя ФОРМАльную проверку.
И все это - о размере.
Эффект замедленного действия.
Скучные невидимые свойства.
Семейство форм - многодокументный интерфейс.
Кратко о свойствах.
Основные события.
События мыши.
События клавиатуры.
Системные события.
ООП - а как насчет полей и методов?

Безопасность прежде всего!

Жизнь полна компромиссов. Машина, о которой вы так мечтаете, страшно прожорлива, однако ее более экономичный собрат выглядит как мыльница на колесах. Вы можете позволить себе либо посещение дорогого спортивно-оздоровительного клуба, где можно накачать мышцы, либо отпуск на берегу моря, чтобы продемонстрировать нового себя (с мышцами), - но не то и другое одновременно. Так же и с Delphi. Имеющиеся параметры позволяют выбирать между безопасностью и скоростью. Программа может быть защищена от ошибок, но это замедлит ее работу и сделает систему громоздкой. Или она может быть компактна и быстра, но при этом более уязвима к ошибкам программиста. Всегда действует правило, если все и везде удачно складывается, значит где-то, что-то вы проморгали. Либо скорость программы, либо ее размеры. И то, и другое, только в сказке про Билла Гейтса и его окна. ;о)

Установка параметров компилятора для повышения безопасности

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

Для обеспечения безопасности следует выбрать команду Options из меню Project и щелкнуть на закладке Compiler, расположенной в верхней части окна. При этом вам откроется "высшее таинство", т.е. страница Compiler из диалогового окна Project Options. В этом окне, будет полным-полно таинственных надписей. Не пугайтесь - альтернативы выбора могут показаться устрашающими, но ваша задача весьма проста. С помощью мыши требуется установить "галочки" рядом со всеми параметрами, за исключением Complete boolean eval. Также нужно поставить "галочки" в выключателе с надписью Default, чтобы все указанные параметры по умолчанию стали действительными для всех последующих проектов. В завершение следует щелкнуть на кнопке ОК.

Когда программа работает идеально и не имеет ни одной ошибки... значит, рак свистнул! Скажем иначе. Когда вам кажется, что программа работает идеально и все выявленные ошибки устранены, некоторые параметры можно отключить, чтобы конечная версия была компактнее и быстрее в работе. Для этого следует опять выбрать Options из меню Project. В группе Runtime errors требуется оставить "галочку" напротив I/O checking и удалить все остальные. При этом может и не произойти сколько-нибудь заметных улучшений таких показателей, как скорость выполнения или размер программы, но иногда это может привести к впечатляющим результатам.

Упрощение логики

Чем плох параметр Complete boolean eval? Попытаемся свести следующее утверждение к виду "Истина/Ложь": "Все коровы синие и все дороколисы желтые." Если вы сразу отвечаете "Ложь", так как не все коровы синие, тем самым вы выполняете так называемое вычисление булевого выражения по сокращенной схеме (short-circuit Boolean evaluation), которое является альтернативой вычислений по полной схеме! Поскольку не все коровы синего цвета, цвет дороколисов значения не имеет, поэтому можно считать, что все выражение имеет результат "Ложь". При вычислении по полной схеме вам пришлось бы выяснять, что же такое дороколисы (douroucoulis - вид ночных обезьян) и действительно ли они желтого цвета (выяснить это предоставляем лично вам).

Иногда вычисления по полной схеме могут быть даже опасны. Например, выражение "х не равен нулю и 1/х меньше 4." Если х равен нулю, мы при сокращенном методе сразу получаем результат "Ложь". В противном же случае при попытке вычисления 1/0 возникнет ошибка - компьютеры не выносят деления на 0! Таким образом, вычисление булевых выражений по полной схеме является одновременно и расточительным, и опасным методом - вот почему этот параметр лучше отключить.

Почему при включенных параметрах группы Runtime errors программа начинает плестись, как черепаха, а ее размер чудовищно увеличиваестя? Delphi добавляет в программу специальный машинный код, призванный в случае возникновения некоторых ошибок сообщать об этом пользователю. Например, если информацию объемом "в десять литров" попробовать разместить в "литровой" переменной, проверка переполнения (overflow checking) сразу выявит ошибку. А если попробовать определить наличие седьмого патрона в револьвере, вас остановит проверка выхода за диапазон (range checking). Но чтобы это стало возможным, в программе при каждом присвоении переменной значения необходимо дописать код, осуществляющий проверку переполнения и диапазона. Если функция вызывается из функции, а та, в свою очередь, из другой функции и т.д., то может не хватить того, что называют емкостью стека. Ошибку этого вида выявляет проверка стека (stack checking). Вот почему каждый вызов функции должен содержать код, осуществляющий проверку стека. В каждом из перечисленных случаев код выявления ошибки состоит всего из нескольких байтов, но все эти байты суммируются!

Диалоговое окно Project Options содержит несколько страниц, идентификаторами которых служат закладки в верхней (или нижней, смотря, какая версия) части окна. В Delphi вам придется встретить еще немало таких многостраничных, нашпигованных закладками окон - более того, Delphi предоставляет возможность употреблять эти самые окна в ваших собственных программах. Все те параметры, которые вы только что установили, расположены на странице Compiler и являются самыми важными. Однако вам не помешает ознакомиться и с остальными.

Страница Directories/Conditionals диалогового окна Project Options, сообщает Delphi, где искать некоторые важные файлы. Программа установки Delphi оставляет эти строки пустыми, потому что все необходимые файлы находятся в одном каталоге с Delphi. Если для расширения Delphi вы приобретаете библиотеки компонентов от независимых производителей, для использования этих библиотек в список Search Path потребуется внести путь к нужному каталогу. Для этого добавьте точку с запятой в конец существующей строки и дальше укажите новый каталог. Например, если строка первоначально имеет вид C:\DELPHI\UNITS, ее можно изменить на C:\DELPHI\UNITS; C:\NEWUTIL. Но не торопитесь покупать дополнительные библиотеки, пока не освоите весь обширный набор встроенных компонентов Delphi!

Строка Output Directory страницы Directories/Conditionals вначале пустая, и заполнять ее не следует Если в эту строку поместить имя каталога, в этот каталог будут сваливаться в одну кучу откомпилированные программные файлы всех проектов. Если строку оставить пустой, откомпилированные файлы будут попадать в те каталоги, где хранятся их исходные файлы.

Страница Application диалогового окна Project Options предоставляет возможность определить некоторые важные атрибуты для окончательного варианта откомпилированного приложения. То, что будет внесено в строку Title, появится под пиктограммой в качестве надписи при минимизации приложения. Увидеть эту пиктограмму вы можете в поле Icon. Для выбора пиктограммы, удовлетворяющей стилю программы, следует нажать кнопку Load Icon... Современные программы для Windows должны всегда иметь файл справки - заполнив строку Help file, можно автоматически ассоциировать такой файл со своей программой.

Страница Forms. Проект может иметь одну или Десяток форм, но одна из них должна быть главной формой. Имя этой формы должно быть представлено в строке Main form и всегда быть первым в списке Auto-create forms. Этот список содержит формы, которые автоматически создаются после запуска программы. Во втором списке представлены остальные формы проекта, которые создаются в процессе работы программы.

Давайте предпочтем безопасность!

Компьютер всегда делает то, что предписывает ему программа, но часто это не те действия, которых вы от него ожидаете. Иными словами, программа в процессе разработки всегда содержит ошибки (независимо от того, написана ли она на Delphi, Visual Basic или суахили). Если в программе с ошибками происходит сбой, в результате может быть нарушена работа самой Delphi. Иногда даже Windows может рухнуть, наполняя вашу душу леденящим ужасом. Именно поэтому лучше работать на Windows более поздней сборки, например XP. Там покруче безопасность и тяжелее ее разрушить. NT тоже не плохая версия.

При разрушении Windows вы теряете все несохраненные данные во всех приложениях, включая последние изменения в компоновке форм и исходном коде Delphi-программы.

Другими словами, эти данные будут неизбежно утеряны, если предпочтения были отданы неправильно. Запомнили? Прекрасно. Вот как предпочтения устанавливаются: выберем Environment Options из меню Tools и взглянем на первую страницу, озаглавленную Preferences. Убедимся, что оба параметра в группе Autosave Options включены, и щелкнем на кнопке ОК. С этого момента при каждом запуске создаваемой вами программы Delphi автоматически сохранит все открытые файлы, компоновку рабочей области Delphi и все изменения настроек. Теперь можно чувствовать себя спокойнее.

Когда Delphi будет сохранять файл, она сохранит предыдущую версию этого файла с расширением ~хх, где хх - первые две буквы расширения этого файла. Например, резервная копия файла UNIT.PAS получит имя UNIT. ~PA, а резервной копией файла UNIT1.DFM будет UNIT1. ~DF. Время от времени вам придется удалять эти резервные файлы с помощью шаблона *.~* (Например у нас в каждой папке проекта есть файл с расширением .bat. Это обычный текстовый файл с командами для DOS. ("Copy *.~* c:\Temp" и вторая строка "del *.~*"), кто знает команды, тот прочитает это так: скопировать все файлы с данной маской в директорию Temp на диске C:\, а затем удалить все файлы с текущей маской. Естественно должна присутствовать папка Temp в указанном месте, иначе будет создан файл с таким именем в корне диска C:\. Остается только периодически очищать папку Temp, куда сбрасываются временные файлы из разных проектов), такая мера позволит избежать многих неприятностей.

Программирование в хорошей форме

Как свойства определяют форму
Различные типы свойств
Дела семейные - родительские и дочерние формы
Присвоение новых значений свойствам различных типов
События, на которые могут реагировать формы
Создание шаблона проекта для программ с главной формой, имеющей фиксированный размер
Как заставить форму реагировать на щелчок мышью или ввод с клавиатуры
Что нужно, чтобы программа спросила "Are you sure?" (Вы уверены?), прежде чем завершить свою работу

Любая обычная программа Windows контактирует с пользователем через прямоугольную область экрана - окно. Именно отсюда и произошло название Windows. В Delphi окнами являются такие компоненты, как формы (forms). Все остальное зависит от формы, поэтому это первый из многочисленных компонентов Delphi, с которым вы столкнетесь при освоении этой системы.
Прежде чем строить новый дом, вы рисуете план, на котором должны быть показаны размер, форма и другие характеристики (свойства) задуманного сооружения. Специальные пометки на плане отображают расположение различных стандартных компонентов - дверей, окон, сантехники и т.д. Когда проект готов, вы передаете его строителям в расчете на то, что построенное здание будет четко соответствовать разработанному проекту.

План программы.

Планом программы в Delphi является форма. Вы создаете программу, определяя свойства формы и располагая на ней стандартные компоненты. Во время работы над программой можно сразу увидеть результат. Не нравится? Можно изменить. Если в конструкции не применяются пиломатериалы и цемент, то внесение изменений - сущие пустяки. К тому же, благоразумие требует постоянной проверки результатов работы.

Каждая создаваемая программа начинается с главной формы, а многие программы имеют и дополнительные формы. Форма - это то, что служит основой программы, все остальное зависит от форм. Без формы не может быть программы. Давайте посмотрим, что можно делать с формами.

"Кажется, я увлекся. То, что каждая программа начинается с главной формы, не совсем правильно. В Delphi можно создать программу, главная форма которой вовсе не будет появляться на экране. Можно даже создать программу, вообще не имеющую главной формы. Однако такие программы имеют довольно необычное устройство и антисоциальное поведение, так как для их создания требуется несколько покопаться во внутренностях Windows. Если вы не признанный знаток Windows, не следует морочить себе голову созданием программ без главной формы."

Производя ФОРМАльную инспекцию.

Предположим, вы должны встретить в аэропорту коллегу, с которым до этого общались исключительно по электронной почте. Как вы опишете себя? Вы, вероятно, предложите перечень примет - ваш рост, цвет волос, имеющиеся татуировки и т.д. Форма Delphi также обладает рядом свойств. Окно Object Inspector (F11) является перечнем, содержащим несколько десятков свойств. Например, заголовок, размер и положение формы на экране - все это свойства. При изменении значения в окне Object Inspector соответственно меняется и форма. Сделать форму изящнее гораздо легче, чем уменьшить собственный вес.

Если вы не можете найти окна Object Inspector на экране, выберите Object Inspector из меню View. Окно имеет две страницы с закладками Properties и Events. Щелкните на закладке Properties и с помощью полосы прокрутки просмотрите все свойства формы. При наличии монитора с высокой разрешающей способностью вам, может, удастся растянуть окно Object Inspector так, чтобы были видны сразу все свойства.

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

Если попробовать выбирать различные свойства, можно заметить различия в способах отображения их значений. Для некоторых свойств рядом с их значениями появляется кнопка с треугольником, направленным вниз. Если щелкнуть на ней, откроется список возможных значений. Другие свойства снабжены кнопкой с тремя точками (...). Нажатие такой кнопки вызовет появление диалогового окна для подстановки значения свойства. Третьи имеют знак "+" перед названием свойства. В этом случае двойной щелчок на имени приведет к раскрытию детального списка подсвойств такого комплексного свойства. Давайте поэкспериментируем и познакомимся, таким образом, с самыми важными свойствами.

Изменение значений визуальных свойств
Самое большое впечатление производят те свойства, которые определяют отображение формы на экране. При изменении одного из таких свойств эффект проявляется моментально. Например, если щелкнуть на свойстве Caption и ввести свое имя - сразу же изменится и заголовок формы. Хотите постоянно иметь перед глазами собственное имя?

Изменение свойства Color формы также существенно меняет внешний облик программы. Существует три различных способа изменения свойства Color - можно выбрать цвет по имени, взять в качестве образца цвет какого-либо элемента Windows на экране или выбрать любой цвет радуги. Если открыть список, то увидим перечень имен, каждое из которых начинается с букв "Cl". Первые несколько пунктов списка представляют имена констант цветов, например clAqua, clNavy, clLime или clWhite. Выбор
одного из цветов приводит к соответствующим изменениям (точный оттенок может немного отличаться, что объясняется использованием различных видеодрайверов).

Оставшиеся в списке пункты могут иметь имена, подобные clScrollBar и clBtnHighligt, которые не являются названиями конкретных цветов. Они соответствуют цветам, которые можно установить с помощью модуля Color в Control Panel Windows. Если выбрать один из этих пунктов, цвет формы будет определен согласно текущей цветовой схеме Windows. Delphi предоставляет вам возможность осуществить рациональный выбор цветов. Например, нет смысла делать цвет формы таким же, как и цвет рамки неактивного окна или выделенные пункты меню. Если вы пишите программу не только для себя, а так оно в основном и получается, то нужно очень внимательно относиться к подобным цветам. Ведь не у всех стоит такая же цветовая гамма. Вы можете получить очень даже неожиданный эффект.

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

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

Выберите один из предлагаемых цветов или нажмите кнопку Define Custom Colors (Определить цвет) и создайте нужный цвет по своему усмотрению. Для сохранения выбранного цвета нужно нажать кнопку Add to Custom Colors (Добавить к цветам пользователя). Если выбранный цвет вас устраивает, щелкните на кнопке ОК. Созданное таким образом значение цвета появляется в списке свойств в виде шестнадцатеричного числа, например $00ВА0ВАВ.

Да, Delphi оперирует этими ужасными шестнадцатеричными числами, где A и F перемешаны с 3 и 4. Люди пользуются десятичными числами (в основе число десять), потому что у них десять пальцев. Компьютеры не имеют пальцев, но считать от нуля до нуля страшно утомительно, поэтому в компьютерах используются двоичные числа (в основе число два). Программисты отдают предпочтение шестнадцатеричным числам, так как одну шестнадцатеричную цифру очень легко представить четырьмя двоичными. К счастью, в Delphi имеются средства, позволяющие преобразовывать десятичные числа в шестнадцатеричные и наоборот.
Для того чтобы конвертировать шестнадцатеричное число в десятичное, следует выбрать Evaluate/Modify из меню Run, ввести шестнадцатеричное число (включая знак доллара в начале) в верхнюю строку и нажать <Enter>. Для преобразования десятичного числа в шестнадцатеричное следует ввести в верхней строке десятичное число, за которым должны следовать запятая и буква h (hex), и нажать <Enter>. Попробуйте проделать это. Вызовите диалоговое окно Evaluate/Modify и в строке Expression введите 12648430,h. Затем нажмите <Enter>, и вы узнаете, какой продукт наиболее важен для программистов!

Двойной щелчок на значении свойства Ctl3D преобразует его из False в True и наоборот. Если присвоить данному свойству значение Тrue, это не вызовет какого-либо видимого эффекта, за исключением того, что цвет формы изменится на clBtnFace. Однако, если добавить в эту форму компоненты, они примут пользующийся популярностью трехмерный вид. Другими словами, компоненты будут как бы высечены на поверхности формы.

Цвета, используемые для скошенных краев элементов управления Ctl3D, соответствуют цветам, употребляемым Windows для экранных кнопок. В модуле Color из Control Panel это Button Face, Button Text, Button Shadow и Button Highlight (Поверхность кнопки, Текст кнопки, Тень кнопки и Выделенная кнопка соответственно). Обычно эти цвета представляют собой оттенки серого, черного и белого, хотя можно использовать и другие цвета.

И все это - о размере

Полдесятка свойств определяют размер и положение формы на экране. Как правило, вам не придется возиться с вводом значений этих свойств вручную - вы просто с помощью мыши будете перемещать форму по экрану и менять ее размер до тех пор, пока она не примет нужный вид. Переместите форму - и тем самым вы измените свойства Left и Тор. Измените ее размер - и вы измените Width и Height. Изменение размера формы также меняет свойства ClientWidth и ClientHeight, которые соответствуют внутренним размерам формы, не включающим рамку, заголовок или меню. Этим свойствам можно присвоить конкретные значения, когда требуется создать форму со специфическими внутренними размерами.

Еще одной парой свойств, связанных с размером формы, являются HorzScrollBar и VertScrollBar. Это комплексные свойства - если на имени такого свойства в Object Inspector дважды щелкнуть мышью, раскроется список из семи подсвойств. Самым важным из них является Range. Каждый раз, когда ClientWidth оказывается меньше HorzScrollBar. Range, форма перерисовывает горизонтальную полосу прокрутки. Каждый раз, когда ClientHeight оказывается меньше VertScrollBar.Range, форма отображает вертикальную полосу прокрутки. Если, например, установить пределы равными 1024 и 768, можно создать форму, которая в режиме 1024x768 будет занимать весь экран, но при уменьшении ее размера, благодаря применению полос прокрутки, останется полностью доступной пользователю.

Прокрутите окно Object Inspector таким образом, чтобы были видны одновременно свойства Height и ClientHeight, и с помощью мыши попробуйте изменять высоту формы. Можно заметить, что изменяются оба свойства, но разница между ними остается постоянной. Введите для ClientHeight конкретное значение и проследите за изменением размера формы. (После нажатия на <Enter> конечно.)
Теперь попробуйте установить для обоих свойств значение -32000 (минус 32000). В результате форма исчезнет с экрана. Вернуть ее на экран можно, сделав Left и Тор равными 0.

Эффект замедленного действия

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

Рядом с именем комплексного свойства Borderlcons находится знак "+", означающий, что двойной щелчок на этом свойстве приведет к раскрытию списка его подсвойств. Появившиеся подсвойства определяют, будет ли форма иметь пиктограмму системного меню, кнопки минимизации и максимизации. Главная форма всегда должна иметь пиктограмму системного меню и почти всегда кнопку минимизации. Если это окно с изменяемыми размерами, оно также должно иметь кнопку максимизации. Delphi умна - если удалить кнопку минимизации или максимизации, соответствующий пункт системного меню будет заблокирован.

Когда редактирование свойств пиктограмм рамки (кнопок управления окном) завершено, следует опять дважды щелкнуть на имени свойства Borderlcons, чтобы закрыть список подсвойств. Если присмотреться к значению Borderlcons, можно заметить, что в квадратных скобках содержится перечень подсвойств, значения которых равны True. Если всем подсвойствам присвоить значения False, значение комплексного свойства сократится до [ ] (пустые квадратные скобки).

Свойство BorderStyle тесно связано со свойством Borderlcons. Оно определяет, может ли пользователь захватить мышкой рамку и изменить размер окна так же, как это делает разработчик во время создания программы. Иногда изменять размер формы бессмысленно. Если на размещение компонентов в форме потрачен целый рабочий день, целесообразно запретить пользователю сокращать форму, в результате чего половина компонентов исчезнет из поля зрения, или увеличивать размер формы, чтобы вокруг компонентов появилось пустое пространство. Для блокирования изменения размеров формы следует ее свойству BorderStyle присвоить значение bsSingle. Чтобы сделать неизменямой вторичную форму, нужно использовать значение bsDialog.

He пытайтесь применять стиль bsDialog для формы, имеющей меню! Благодаря одной странной особенности, заключающейся в самой Windows (не во всех версиях), такая комбинация приводит к появлению пустого (и жуткого) пространства вокруг меню. Следует также иметь в виду, что при использовании этого стиля форма не будет иметь кнопки минимизации и максимизации. Обыкновенное диалоговое окно.

Свойство Position сообщает Delphi, важны ли размер и расположение формы на экране, определенные во время разработки. По умолчанию свойство poDesigned означает, что изначально форма будет иметь расположение и размеры, определенные во время разработки. Значение poDefault предоставляет выбор и размера, и места окна на откуп Windows, a poDefaultSizeOnly и poDefaultPosOnly позволяют Windows определить соответственно либо размеры, либо место. Наконец, poScreenCenter сохраняет размеры, определенные при разработке, но располагает форму в центре экрана, независимо от того, с каким видеорежимом работает в данный момент Windows. Ну и, само собой разумеется, если свойству BorderStyle формы присвоить значение, отличное от bsSizeable, Windows не сможет управлять размерами и местоположением формы, независимо от значения Position.

Исходный внешний вид программы на экране определяется свойством WindowState. Как правило, для большинства программ вполне приемлемо значение, установленное по умолчанию, - wsNormal. Если изменить его на wsMinimized, программа при запуске минимизируется в пиктограмму. Если использовать значение wsMaximized, программа займет весь экран.

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

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

Изменение свойства Font не будет иметь видимого эффекта, если в форму не включить некоторых компонентов. По умолчанию компоненты автоматически отображают текст, используя шрифт старшей формы. Существует два способа изменить это свойство. Можно щелкнуть на кнопке подстановки (...), чтобы вызвать стандартное диалоговое окно Windows Font (Шрифт), или дважды щелкнуть на имени свойства для того, чтобы раскрыть список подсвойств. Свойство Font является комплексным - его подсвойство Style также может детализироваться, позволяя устанавливать стили полужирный, курсив, подчеркивание и перечеркивание.

Шрифтом, принятым по умолчанию для форм и компонентов Delphi, является MS Sans Serif, Можно выбрать любой шрифт, но желательно, чтобы это был шрифт TrueType или шрифт, подобный MS Sans Serif, имеющий наборы символов разных размеров. Иначе может оказаться, что при использовании некоторых видеодрайверов расположение меток и компонентов формы исказится.
Если минимизировать форму Delphi, она свернется в пиктограмму, по умолчанию применяемую Delphi, если только, свойство Icon не указывает на пиктограмму, специфичную для этого приложения. Прежде чем какое-либо приложение Delphi попадет к конечным пользователям, вы, видимо, захотите снабдить каждую из его форм оригинальной пиктограммой. Можно использовать одну из пиктограмм, поставляемых с Delphi, а можно нарисовать собственную с помощью Image Editor Delphi - для этого надо выбрать Image Editor из меню Tools. Вы, вероятно, также захотите, чтобы "Проводник" использовал вашу пиктограмму при отображении приложения в окне группы. Для этого необходимо, чтобы свойство Icon приложения имело то же значение, что и свойство Icon главной формы.

Для того чтобы назначить приложению пиктограмму, необходимо выбрать Options из меню Project и щелкнуть на закладке Application.
Часто возникает необходимость сохранить относящиеся к форме какие-либо данные, для которых не предусмотрено соответствующего свойства. Если эту информацию можно представить в виде числа, для нее используется свойство Tag. Этим свойством обладает каждый компонент, и мы будем часто использовать его в примерах.

Скучные невидимые свойства.

Если вы наблюдательны, то могли заметить, что не были упомянуты многие из свойств, представленных в Object Inspector. Это объясняется тем, что нет никакой необходимости в использовании сразу всех свойств, во всяком случае на первых порах. Но если вам не терпится узнать, чего вы лишились, здесь приводится краткий обзор остальных свойств форм. Если свойству Enabled присвоить значение False, форма окажется полностью заблокированной. Необходимо предусмотреть какой-либо встроенный в программу способ разблокировки формы, иначе вы не сможете выйти из этой программы! Вам редко придется изменять данное свойство для формы. Однако, когда вы загружаете вторичную форму в качестве модального диалогового окна, она автоматически блокирует главную форму до завершения своей работы.

Свойства Hint и ShowHint используются при создании контекстно-зависимой справки в программе. Если ShowHint имеет значение True, строка, которую вы введете для свойства Hint компонента, отобразится в поле помощи, когда курсор мыши задержится над этим компонентом. Если ShowHint устанавливается в True, свойство Hint формы следует оставить незаполненным. Можно также оставить ShowHint установленным в False и тем самым организовать для активного компонента отображение строки Hint в строке состояния.
Несмотря на то, что Windows является средой, ориентированной на применение мыши, очень важно предусмотреть в своей программе использование клавиатуры в качестве альтернативы. Иногда клавиш мнемонического доступа (подчеркнутые буквы пунктов меню и закладок) и специальных комбинаций клавиш для пунктов меню оказывается просто недостаточно. В таком случае свойству KeyPreview можно присвоить значение True, что позволит вашей форме обрабатывать нажатия большинства клавиш до того, как их перехватит активный управляющий элемент. Позже мы научимся создавать меню: и обычные, расположенные в верхней части экрана, и всплывающие, появляющиеся рядом с курсором мыши. Свойство Menu является идентификатором главного меню формы, а свойство PopupMenu - меню, которое появляется автоматически при щелчке правой кнопкой мыши на форме.

Delphi автоматически присваивает свойству Name первой формы значение Form1, второй - Form2 и т.д. Имя применяется для идентификации формы и служит для внутреннего использования. При желании имена можно изменить, например, на MainForm, InputForm или IRSForm1040 (и это обязательно необходимо делать). По умолчанию свойство Visible главной формы имеет значение True, а всех вторичных форм (первоначально) - False. Необходимость иметь дело с этим свойством возникает очень редко. Хотя, если вы хотите при загрузке программы увидеть сразу несколько форм (например, как у Delphi), то необходимо поставить их свойства Visible в True.

Семейства форм - многодокументный интерфейс

Иногда одного большого окна недостаточно. Многодокументный интерфейс Windows (Multiple Document Interface - MDI) позволяет программам использовать другие окна, существующие внутри главного окна. Главное окно называется родительским, а его помощники - дочерними окнами. Программа MDI похожа на миниатюрную версию Program Manager Windows 3.11 - в своих границах она может располагать дочерние окна мозаикой или каскадом, а также минимизировать их в пиктограммы в нижней части главного окна. Дочерние окна могут относиться либо к одному типу (например, окна редактирования текста, в которых открыты различные файлы), либо к разным (например, частично окна редактирования текста, а частично - окна просмотра растровых изображений). Наиболее известным примером программы MDI является Program Manager: его дочерние окна - это окна групп.

Определяет то, что форма Delphi является обычным окном, родительским окном MDI или дочерним окном MDI, свойство FormStyle. Главная форма программы никогда не определяется как дочернее окно MDI.

Прежде чем перейти к следующему набору команд, выберите New Project из меню File, что позволит начать работу с новой пустой формы. Создавайте новую форму каждый раз, когда приступаете к изучению чего-нибудь нового, если только специально не будет сказано об использовании ранее созданной программы.

Выберите New Form из меню File - в результате в проект будет добавлена вторая форма Form2. Для свойства FormStyle Form2 установите значение fsMDIChild, а для свойства FormStyle формы Forml - значение fsMDIForm. Свойство Visible вторичной формы по умолчанию имеет значение False - измените его на True.

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

Форма MDI, созданная Delphi, обладает встроенными возможностями располагать дочерние окна мозаикой или каскадом и аккуратно размещать пиктограммы вдоль своего нижнего края.

Минуточку! Следует сказать еще кое-что. Свойство FormStyle может принимать еще одно значение - StayOnTop. При выборе этого значения форма будет "плавать" поверх других программ, даже когда она неактивна, подобно панели задач из Windows (кнопка пуск и т.д.). Это может мешать, если под плавающей формой окажется что-нибудь важное, поэтому, если используется стиль StayOnTop, лучше установить как можно меньший размер для формы. Хотя это можно использовать для запрета пользователю работать, пока не будет введен пароль. Свернуть окно не удастся (если вы это не позволите), а пользоваться дальше программой, да и всей операционкой, при соответствующих функциях будет очень даже не удобно. Хотя все можно обойти, но это уже тема для отдельного разговора. Необходимо добиться ситуации, когда обойти защиту программы было бы тяжелее (читай дольше), чем написать что-либо подобное.

Кратко о свойствах.

В этом лекционном материале рассматривались некоторые из простых свойств - давайте припомним и систематизируем их.
Комплексные объектные (exploding object) свойства. Значением является имя объекта, например (TFont). Перед именем находится знак "+", а рядом со значением - кнопка подстановки с тремя точками. Нажатие кнопки приводит к появлению диалогового окна, а двойной щелчок на имени - к разворачиванию списка подсвойств. Пример: Font.

Свойства со списком (list). Рядом со значением свойства появляется кнопка с изображенным на ней треугольником. Щелчок на треугольнике приводит к появлению списка возможных значений. Двойной щелчок на значении приводит к выбору следующего пункта списка. Если текущее значение оказывается в списке последним, выбирается первый пункт. (Свойство Color похоже на свойство со списком, но это особый случай.) Примеры: WindowState, Cursor, FormStyle.

Числовые (numeric) свойства. Здесь в качестве значения вы можете ввести все что угодно, но информация, не являющаяся числом, принята не будет. В большинстве случаев недопустимые числовые значения конвертируются в приемлемые значения. Например, значение ClientHeight, равное -1, будет конвертировано в 0 Примеры: Left, Height, Top.

Объектные (object) свойства. В качестве значения отображается (None) или имя объекта, например (TIcon), а рядом - кнопка подстановки (...) Нажатие кнопки вызывает появление стандартного диалогового окна выбора файла. Пример: Icon.
Свойства с множествами (set). Перед именем свойства имеется знак "+", а значение представляет собой список слов в квадратных скобках. Если дважды, щелкнуть на имени, свойство развернется в список подсвойств со значениями True/False. Примеры: Borderlcons, HorzScrollBar, VertScrollBar.

Свойства со списком строк (string-list). Отображается значение (TStrings), а рядом с ним появляется кнопка подстановки. Нажатие кнопки вызывает специальный редактор, который позволяет ввести список строк. Компонент Form не обладает свойствами такого типа, но чуть дальше вы встретитесь с этим свойством у других компонентов.

Свойства со значениями True/False. Рядом со значением появляется кнопка выбора (треугольник направленный вниз). Щелчок на кнопке выбора приводит к отображению списка, содержащего только значения True и False. Двойной щелчок на значении изменяет его на противоположное. Примеры: Ctl3D, Enabled, Visible.

Свойства "Подходит все". Несколько свойств в качестве значения примут почти все, что можно ввести с клавиатуры. Если будет введено неприемлемое значение, Delphi его отвергнет - попробуйте, например, ввести Visual Basic в качестве значения свойства Name. Примеры: Caption, Hint.

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

Основные события.

Пусть поднимет руку тот, кто уже научился программировать в DOS. Вы подняли руку? Если нет, значит, вы обладаете преимуществом. Программирующие под управлением DOS привыкли изображать программу как последовательность команд: пойди в магазин и купи сыру, ЕСЛИ (IF) он есть в продаже, ТОГДА (THEN) купи пару килограмм - приблизительно так. Они исходят из того, что компьютер выполняет команды последовательно, время от времени переходя в цикл или под управление подпрограммы. Если вы подняли руку, будьте особенно внимательны, так как программирование для Windows - это не то, к чему вы привыкли.

После того как программа для Windows загрузилась в память и выполнила некий код инициализации, она ничего не делает. Совсем ничего. Здесь нет "следующего шага". Ничего не происходит, пока не произойдет некоторое событие (event) - только в этом случае вы ощутите реакцию компьютера. Вместо списка команд она содержит набор алгоритмов, определяющих ее действия для различных событий. В Delphi эти планы носят название обработчиков событий (event handlers) и призваны реагировать на множество различных событий.

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

События мыши

Для начала вы создадите программу, меняющую вид курсора при каждом нажатии кнопки мыши. Если щелкнуть на свойстве Cursor, а затем на клавише со стрелкой, появится список значений от crArrow до crVSplit. Несколько экспериментов покажут, что для формы эффект значения crDefault тот же, что и crArrow. Каждое значение имеет свой числовой эквивалент в пределах от -14 (crVSplit) до 0 (crDefault).

Для того чтобы узнать числовое значение имени-константы, например crVSplit, требуется нажать <Ctrl+F7>, в результате чего появится диалоговое окно Evaluate/Modify. В строке Expression нужно ввести имя константы и нажать <Enter>. Следует иметь в виду, то это возможно только после успешной компиляции или запуска проекта на выполнение.

В качестве первого шага создания обработчика события следует точно определить, что должно произойти. Компьютер всегда делает именно то, что указано делать, - ни больше и ни меньше. Если указание не совсем точно соответствует вашему желанию, компьютер вас не поправит. Поэтому, например, недостаточно сказать, что каждый раз, когда пользователь щелкает мышью, вид курсора должен меняться согласно следующему значению в списке. Необходимо также определить, что, когда курсор находится на последнем значении (crDefault), дальше он должен перейти на первое значение (crVSplit). Если попробовать выразить это ломаным английским, получим:

IF Cursor equals crDefault THEN
    Set Cursor equal to crVSplit
OTHERWISE
    Set Cursor equal to the next value.

Как вы увидите позже, это прекрасно транслируется в код Delphi.

Щелкните один раз на закладке Events в окне Object Inspector, затем дважды - на колонке обработчика событий рядом с событием OnClick. На переднем плане появится Code Editor с помещенной сразу в нужное место модуля заготовкой обработчика события OnClick. Остается только ввести код между строками begin и end обработчика событий.

Там, где находится курсор, следует ввести следующий код:

IF Cursor = crDefault THEN
  Cursor = crVSplit
ELSE
  Cursor = Succ(Cursor);

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

Встроенная функция Succ возвращает следующее значение переменной Cursor. А точка в конце предложения заменена на точку с запятой. Не так уж сложно, не так ли?

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

IF Cursor = crDefault THEN Cursor = crVSplit
ELSE Cursor = Succ(Cursor);

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

Запустите программу и щелкните мышью на форме несколько раз. При каждом щелчке курсор будет менять форму. После того как вы переберете все формы курсора, цикл начнется сначала. Ясно? Вы создали программу, реагирующую на события мыши! Другими событиями мыши являются OnDblClick, OnMouseDown, OnMouseMove и OnMouseUp, а также OnDragOver и OnDragDrop. Об этих событиях мы будем говорить позже.

События клавиатуры

Теперь мы создадим программу перемещения формы по экрану при нажатии клавиш управления курсором. Она должна реагировать на нажатия клавиш перемещением формы на восемь пикселей в соответствующем направлении.

Сделайте форму узкой, насколько это возможно, и измените ее высоту так, чтобы она приблизительно была равна ширине. Свойству BorderStyle присвойте значение bsSingle, затем дважды щелкните на свойстве Borderlcons и присвойте biMaximize значение False.

Для обработчика события OnKeyDown введите следующий код.

CASE Key OF
    VK_LEFT: Left := Left - 8;
    VKUP: Top := Top - 8;
    VK_RIGHT: Left := Left + 8;
    VK_DOWN: Top := Top + 8;
END;

(Для того чтобы ввести код для конкретного события, следует дважды щелкнуть на колонке обработчика события справа от имени этого события. Delphi создаст шаблон для обработчика, и вы введете код между строками begin и end шаблона.)

Примененная здесь синтаксическая конструкция CASE выглядит сложнее, чем оператор IF-THEN в последнем примере, но, в сущности, они мало чем отличаются. Delphi предает обработчику событий переменную Key. Переменная Key содержит код, определяющий, какая клавиша нажата, а оператор CASE сравнивает эту переменную с четырьмя конкретными цифрами.
Что? Вы говорите, VK_LEFT - не число? Именно так. Четыре имени, начинающиеся на VK, являются константами (constants) - описательными именами, представляющими какие-то числа. Эти константы можно заменить числами 37, 38, 39 и 40. Однако, голые цифры не вызывают никаких ассоциаций. Но когда используется имя-константа, сразу ясно, что 37 здесь является идентификатором виртуальной клавиши (Virtual Key, VK) "стрелка влево".

После того как программа успешно откомпилирована или запущена, c помощью диалогового окна Evaluate/Modify можно узнать числовое значение имени-константы. Следует нажать <Ctrl+F7>, ввести имя константы и нажать клавишу < Enter>.

Давайте добавим еще один обработчик события клавиатуры, чтобы программа завершала работу при нажатии клавиши <Q>. Для этого обработчика можно использовать событие OnKeyPress. Чем данное событие отличается от OnKeyDown или OnKeyUp? OnKeyPress срабатывает после нажатия клавиши, и система идентифицирует ее как клавишу с простым символом, например <А> или <!>, а не как клавишу управления курсором, функциональную клавишу, комбинацию <Аlt + клавиша> и т.д.

Давайте, не открывая нового проекта, создадим для формы обработчик события OnKeyPress, содержащий одну-единственную строку:
IF UpCase(Key) = 'Q' THEN Close;

Функция UpCase встроена в Delphi. При передаче ей буквы алфавита она возвращает эту букву как прописную. При передаче любого другого символа функция возвращает символ без изменения.

Запустим программу и попробуем испытать ее. При нажатии клавиш управления курсором форма послушно перемещается в соответствующем направлении. Если нажать <Q>, программа завершит работу. Строго говоря, это довольно странное и необычное использование событий клавиатуры - существуют другие способы переместить и закрыть форму. Но на данном примере вам будет легко понять принципы работы с событиями клавиатуры.

Системные события

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

Основные системные события

Событие
Ситуация
Реакция пользователя
OnActive Форма только что стала активным окном программы Обновление любой информации, отображенной в форме
OnClose Имело место событие OnCloseQuery, в результате чего форма закрывается Последняя возможность отменить закрытие формы
OnCloseQuery Windows запрашивает форму, не намерена ли она закрыться Пользователю предлагается сохранить все изменения данных или отменить закрытие
OnCreate Создание формы Выполнение необходимой инициализации
OnDeactivate Форма только что перестала быть активным окном программы Отмена всех действий, выполняющихся в обработчике события OnActivate
OnDestroy Форма готова исчезнуть навсегда Очистка всех ресурсов, выделенных программой
OnPaint Форму необходимо отобразить заново, так как она, например, была только что открыта или восстановлена из пиктограммы Рисование линии или простейшей графической фигуры непосредственно в форме
OnResize Размеры формы были изменены Приведение в порядок размеров или расположения компонентов после изменения размеров формы

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

CanClose := MessageDlg ('Действительно хотите закрыть?', mtConfirmation, [mbYes, mbNo], 0) = IDYES;

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

MessageDlg является функцией, предоставляемой Delphi для организации диалога программы с пользователем. Это более сложная функция, чем UpCase, использованная нами раньше, и ей необходимо передать четыре элемента информации, называемые параметрами (parameters) или аргументами (arguments).

Первым параметром является сообщение, которое вы хотите отобразить на экране, заключенное в одинарные кавычки. Второй параметр представляет собой константу, определяющую тип диалогового окна. Возможные значения - константы mtWarning, mtError, mtlnformation и mtConfirmation. С каждой константой ассоциирована специальная пиктограмма, и для каждой имеется специфический заголовок диалогового окна. В нашем случае пиктограмма имеет вид большого знака вопроса, а заголовок - Confirm (подтвердите).
Третьим параметром служит набор констант, определяющих, какие кнопки должны присутствовать в диалоговом окне. Список заключен в квадратные скобки и может содержать mbYes, mbNo, mbOk, mbCancel и mbHelp. Если в списке присутствует mbHelp и ваша программа имеет связанный с ней файл справки Windows, нажатие кнопки Help вызовет появление темы справки, ассоциированной с числом в четвертом параметре. Наконец, функция MessageDlg возвращает константу, определяющую, какую кнопку нажал пользователь. Если возвращенным значением является не IDYES, программа не сможет завершить своей работы. Мы не будем злоупотреблять использованием функции MessageDlg.

ООП - а как насчет полей и методов?

Если вы пытались познакомиться с объектно-ориентированным программированием (ООП) и уловили его суть, вы могли заметить определенное сходство между объектами и формами. В объекте имеются поля, содержащие информацию, и методы, производящие действия над информацией. Форма обладает свойствами, содержащими информацию, и обработчиками событий, воздействующими на информацию. Действительно, Delphi является системой ООП. Свойство аналогично информационному полю, а обработчик события обладает сходством с методом. Саму же форму можно считать объектом типа TForm. Формы и другие компоненты программ Delphi могут также иметь информационные поля, которые не являются свойствами, и методы, не являющиеся обработчиками событий. Так, в примере события клавиатуры, разобранном нами ранее, вызывалась функция Close для прекращения работы программы - Close здесь является методом объекта-формы.

Свойства и обработчики событий - важные элементы программирования в Delphi, и им уделяется значительное внимание. Однако при написании кода реакции на события мы время от времени будем использовать информационные поля, не являющиеся свойствами, и методы, не являющиеся обработчиками событий. Более подробно с объектами, полями и методами мы познакомимся позже. А до того вы приобретете необходимый опыт, используя их в примерах программ.

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

И последнее. Если вы считаете, что ваша программа безупречна, значит вы плохой программист. Если в вашей программе нет ошибок - это значит, что вы их там не нашли, и абсолютно не утверждает, что их там нет.

Идеи и пожелания с удовольствием почитаем.

Хостинг от uCoz