Шаг 2.
Основы визуального программирования

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

    Программирование в Delphi строится на тесном взаимодействии двух процессов:

    Для написания кода используется окно кода, для конструирования программы - остальные окна Delphi, и прежде всего - окно формы.

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

    К оглавлению

Пустая форма и ее модификация

    Как уже говорилось, окно формы содержит проект Windows-окна программы. Важно помнить, что с самого начала работы над новой программой Delphi создает минимально необходимый код, обеспечивающий ее нормальное функционирование в Windows. Таким образом, простейшая программа готова сразу после выбора опции File | New | Application, и нам остается просто запустить программу. Однако до этого советую выполнить две важные вещи: создать собственный рабочий каталог (папку) и нужным образом настроить Delphi.

    К оглавлению

Настройка Delphi

    В процессе работы над проектами программ вам понадобится создать множество форм и модулей. Полезно сохранять эти данные в виде дисковых файлов в отдельной папке. Более того, для каждой программы в этой папке имеет смысл создать свою вложенную папку. Тогда, чтобы освободить место на диске для серьезной программы, вам будет достаточно уничтожить основную папку, а чтобы передать ту или иную учебную программу своему коллеге - переписать на дискету содержимое соответствующей вложенной папки. Создайте папку с именем, например, MY_DELPH, а в нем - вложенную папку для вашей первой программы. Чтобы не утруждать себя придумыванием подходящих имен для “безликих” учебных программ, советуем использовать для папки имя pgm_1 или что-нибудь подобное.

    Второе, что нам предстоит сделать, - это внести изменения в стандартную настройку среды Delphi. Это необходимо для того, чтобы среда автоматически сохраняла на диске последнюю версию создаваемой вами программы. Выберите опцию меню Tools | Environment options и убедитесь, что в появившемся диалоговом окне активна вкладка Preferences. В левом верхнем углу этой страницы в группе Autosave | Options есть переключатели Editor Files и Desktop (в других версиях Delphi эти переключатели располагаются в правом верхнем углу). Активизация переключателей приведет к автоматическому сохранению текста окна кода программы и общего расположения окон Delphi перед началом очередного прогона создаваемой программы, что избавит вас от возможных потерь в случае “зависания” программы. Советуем активизировать эти переключатели, щелкнув по каждому мышью. Чтобы следить за ходом компиляции, активизируйте также переключатель Show Compiler progress в группе Compiling and Running. Далее, мне кажется полезным сохранять в коде программы комментарии - текстовые фрагменты, которые не влияют на работу программы, но делают ее текст более понятным. Если вы предпочитаете использовать комментарии на русском языке, следует выбрать соответствующий шрифт для отображения кода программы. По умолчанию редактор Delphi использует шрифт Courier New, в котором может не быть символов кириллицы. В этом случае выберите опцию Tools | Editor options и на странице Display в строке Editor Font установите Courier New Cyr (для предыдущих версий страница Display доступна в окне Tools | Environment Options).

    Теперь все готово для прогона вашей первой программы. Щелкните мышью по кнопке в главном окне или, что проще, нажмите клавишу F9: именно таким способом подготовленная Delphi-программа последовательно проходит три главных этапа своего жизненного цикла - этапы компиляции, компоновки и исполнения. На этапе компиляции осуществляется преобразование подготовленного в окне кода текста программы на языке Object Pascal в последовательность машинных инструкций, на этапе компоновки к ней подключаются необходимые вспомогательные подпрограммы, а на этапе исполнения готовая программа загружается в оперативную память и ей передается исполнение.

    Как только вы нажмете F9, появится диалоговое окно Save Unit1 As, в котором Delphi попросит вас указать имя файла для модуля Unit1.pas и папку его размещения.


    Замечание. По умолчанию Delphi предлагает разместить файл модули и проекта в системной папке BIN. Поскольку эта папка содержит жизненно важные для Delphi файлы, обязательно измените ее на вашу рабочую папку (например, MY_DELPH).

    Лучше не идти на поводу у Delphi и не соглашаться с предложенным именем Unit1.раs, а присвоить модулю какое-нибудь более запоминающееся имя. Например, назовем модуль my_ist_u, что, по мысли автора, должно расшифровываться как “мой_первый_модуль”. Если в окне Save Unit As вы укажете такое имя и нажмете Enter, Delphi попросит задать имя еще и для проекта программы в целом. Под этим именем будет создан исполняемый ЕХЕ-файл, например, firstpgm.

    К оглавлению

Имена в Delphi

    Поскольку речь зашла об именах, мы должны объяснить свою странную приверженность к сокращенным англоязычным именам. Дело в том, что Delphi "не признает" ни русских, ни французских, ни китайских, ни вообще каких бы то ни было имен, в которых используются символы, отличные от латинских букв, цифр и знака подчеркивания, причем имя не должно начинаться цифрой, но может начинаться знаком подчеркивания. Так как в этом перечне нет пробела, имена не могут также состоять из нескольких слов. Далее, сокращения до не более чем 8 символов - это дань ограничениям Delphi версии 1. Эта версия рассчитана на работу под управлением Windows З.х, которая не признает длинных имен файлов. Если вы работаете с 32-разрядной версией Delphi (т. е. с любой из версий от 2-й до 6-й), можете не сокращать имена и написать my_first_unit или даже moy_pervij_modul, потому что эти версии рассчитаны на современные 32-разрядные операционные системы, разрешающие использовать длинные имена файлов.

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

    К оглавлению

Изменение свойств формы

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

    Теперь попробуем разобраться с тем, что такое модуль. В первом приближении мы можем считать модулем самостоятельный раздел программы, в чем-то подобный главе в книге. Модуль создается каждый раз, когда вы создаете новую форму (в программе может быть и, чаще, бывает не одна, а несколько - иногда несколько десятков форм и связанных с ними модулей). При компиляции программы Delphi создает файлы с расширениями PAS, DFM и DCU для каждого модуля: PAS-файл содержит копию текста из окна кода программы, в файле с расширением DFM хранится описание содержимого окна формы, а в DCU-файле - результат преобразования в машинные инструкции текста из обоих файлов. Файлы DCU создаются компилятором и дают необходимую базу для работы компоновщика, который преобразует их в единый загружаемый файл с расширением EXE.

    Попробуем модифицировать программу, например, изменим заголовок ее окна. По умолчанию заголовок окна совпадает с заголовком формы: Form1. Чтобы изменить заголовок, нужно обратиться к окну Инспектора объектов. Закройте окно работающей программы Form1 (если вы еще не сделали этого) и щелкните мышью по строке Caption


    Замечание. Окно Инспектора объектов не видно в момент прогона программы. Если после нажатия на клавишу F11 окно Инспектора объектов не появилось на экране, проверьте состояние панели задач Windows - вы наверняка увидите в ней имя вашей программы. Закройте ее.

    Теперь правая колонка этой строки с текстом Form1 выделена цветом и справа от выделенного виден текстовый мигающий курсор. Переключите клавиатуру в режим ввода кириллицы и введите Моя первая программа, после чего еще раз нажмите F9. Новый прогон программы создаст окно с заголовком “Моя первая программа”, что несет в себе гораздо больше информации, чем просто Form1.

    Итак, простым изменением содержимого строки в окне Инспектора объектов мы добились важной перемены: изменили одно из свойств окна программы - его заголовок. Таким же образом можно изменять любое другое свойство формы.

    К оглавлению

Размещение нового компонента

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

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

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


Рис.1. Размещение компонента Label

    Новый компонент имеет стандартное имя Label1, и надпись на нем повторяет это имя. Изменим эту надпись: с помощью строки Caption окна Инспектора объектов введите надпись: Я программирую на Delphi. Как только вы начнете вводить новую надпись, вид компонента на форме начнет меняться, динамически отражая все изменения, производимые вами в окне Инспектора объектов.

    Выделим надпись цветом и сделаем ее шрифт более крупным. Для этого щелкните мышью по свойству Font окна Инспектора объектов и с помощью кнопки в правой части строки раскройте диалоговое окно настройки шрифта. В списке Size (Размер) этого окна выберите высоту шрифта 24 пункта, а с помощью списка Color (Цвет) выберите нужный цвет (например, красный), после чего закройте окно кнопкой OK.


    Замечание. Пункт - 1/72 дюйма, т. е. приблизительно 0,04 мм. Таким образом, 24 пункта означает высоту шрифта чуть более 9 мм.

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

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

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

    Заметим, что все визуальные компоненты (в Delphi могут использоваться как визуальные, так и невизуальные компоненты. Невизуальные компоненты не отображаются при выполнении программы) имеют свойства Left (Слева), Top (Сверху), Width (Ширина) и Height (Высота), числовые значения которых определяют положение левого верхнего угла компонента и его размеры в так называемых пикселях, т. е. в минимальных по размеру точках экрана, светимостью которых может управлять программа. При буксировании компонента или изменении его размеров мышью эти значения автоматически меняются и наоборот - изменение этих свойств в окне Инспектора объектов приводит к соответствующему изменению положения и размеров компонента. В Delphi 4, 5 и 6 значения Left и Top автоматически появляются в небольшом окне рядом с указателем мыши при буксировке компонента по форме.

    К оглавлению

Реакция на события

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

   

Модификация формы

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

    Компонент кнопка изображается пиктограммой на странице Standard палитры компонентов. Поместите этот компонент на форму и расположите его ниже метки и посередине формы (рис.2).


Рис.2. Форма со вставленной кнопкой

    К оглавлению

Обработчик события OnClick

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

    Этот фрагмент должен представлять собой последовательность текстовых строк, в которых программист указывает, что именно должна делать программа в ответ на нажатие кнопки. Фрагмент оформляется в виде специальной подпрограммы языка Object Pascal - процедуры.

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

procedure TForm1.Button1Click(Sender: TObject);
begin

end;

    Попробуем разобраться в том, что он содержит. Слово procedure извещает компилятор о начале подпрограммы-процедуры (в Delphi могут использоваться также подпрограммы-функции; в этом случае вместо procedure (процедура) используется слово function (функция). За ним следует имя процедуры TForm1.Button1Click. Это имя - составное: оно состоит из имени класса TForm1 и собственно имени процедуры Button1Click.

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

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

type
    TForm1 = class(TForm)
          Button1: TButton;
          Label1: TLabel;
          procedure Button1Click(Sender: TObject);
    private
           { Private declarations }
    public
           { Public declarations }
    end;

var
    Form1: TForm1;

    Строка

    TForm1 = class(TForm)

определяет новый класс TForm1, который порожден от (создан по образцу) стандартного класса TForm. Строка

    Form1: TForm1;

создает экземпляр этого класса с именем Form1. Стандартный класс TForm описывает пустое Windows-окно, в то время как класс TForm1 описывает окно с уже вставленными в него компонентами метка и кнопка. Описание этих компонентов содержат строки:

          Button1: TButton;
          Label1: TLabel;

Они указывают, что компонент Button1 представляет собой экземпляр стандартного класса TButton, а компонент Label1 - экземпляр класса TLabel.

    За именем процедуры TForm1.Button1Click в круглых скобках следует описание параметра вызова:

      Sender: TObject

(параметр с именем Sender принадлежит классу TObject). Как мы увидим дальше, процедуры могут иметь не один, а несколько параметров вызова или не иметь их вовсе. Параметры вызова (если они есть) служат для настройки реализованного в процедуре алгоритма на выполнение конкретной работы. Параметр Sender вставлен Delphi “на всякий случай”: с его помощью подпрограмма Button1Click может при желании определить, какой именно компонент создал событие OnClick. Вся строка в целом:

     procedure TForm1.Button1Click(Sender: TObject);

называется заголовком процедуры. Три следующие строки определяют тело процедуры:

begin

end;

    Слово begin (начало) сигнализирует компилятору о начале последовательности предложений, описывающих алгоритм работы процедуры, а слово end (конец) - о конце этой последовательности. В нашем случае тело процедуры пока еще не содержит описания каких-либо действий, что и неудивительно: Delphi лишь создала заготовку для процедуры, но она ничего “не знает” о том, для чего эта процедура предназначена. Наполнить тело нужными предложениями - задача программиста.

    Для нас важно то обстоятельство, что каждый раз при нажатии кнопки Button1 управление будет передаваться в тело процедуры, а значит, между словами begin и end мы можем написать фрагмент программы, который будет выполняться в ответ на это событие.

    Чтобы убедиться в этом, сделаем нашу кнопку “звучащей”: напишите в пустой строке между словами begin..end следующее предложение:

   MessageBeep (МВ_ОК);

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

    К оглавлению

Динамическое изменение свойств компонента

    Поскольку кнопка Button1 в нашей программе способна “звучать”, полезно изменить ее надпись: вместо умалчиваемой надписи Button1, которую автоматически формирует Delphi по имени компонента, назовем кнопку, например, “Звук”. Проще всего это сделать с помощью окна формы и Инспектора объектов, т. е. на этапе конструирования формы (для этого нужно просто изменить свойство Caption компонента Button1 в окне Инспектора объектов), но для более полного знакомства с Delphi мы рассмотрим другой способ - динамического (К сожалению, эта процедура работает не всегда: если ваш компьютер не оснащен звуковой картой, динамик будет молчать. В этом случае вместо MessageBeep (MB_OK) напишите просто Веер. Изменения на этапе конструирования называются статическими, а в ходе выполнения программы - динамическими.) изменения надписи на этапе прогона программы. Для этого создадим обработчик события OnCreate для формы и изменим в нем это свойство.

    Событие OnCreate возникает после создания Windows-окна, но до появления этого окна на экране. Чтобы создать обработчик этого события, раскройте список компонентов в верхней части окна Инспектора объектов, выберите компонент Form1 и дважды щелкните по свойству OnCreate на странице Events этого компонента (щелкать нужно по правой части строки OnCreate). В ответ Delphi вновь активизирует окно кода и покажет вам заготовку для процедуры TForm1.FormCreate. Отредактируйте ее следующим образом:

procedure TForm1.FormCreate(Sender: TObject);
begin
   Button1.Caption:= 'Звук';
end;

    Единственная вставленная нами строка представляет собой так называемый оператор присваивания языка Object Pascal. В левой части оператора указывается свойство Button1.Caption, а в правой части - значение 'Звук', которое мы хотим придать этому свойству. Связывает обе части комбинация символов “:=”, которая читается как “присвоить значение”. Символы “:=” всегда пишутся слитно, без разделяющих пробелов, хотя перед двоеточием и после знака равенства можно для лучшей читаемости программы вставлять пробелы, что мы и сделали. Как и любое другое предложение языка, оператор присваивания завершается точкой с запятой.

    Составное имя Button1.Caption необходимо для точного указания компилятору, о каком свойстве идет речь: в нашей программе используются три компонента (включая саму форму), каждый из которых имеет свойство Caption; уточняющий префикс Button1 заставит изменить это свойство у кнопки, а не у метки или формы. Присваиваемое свойству значение является текстовой строкой. По правилам Object Pascal текстовая строка должна заключаться в обрамляющие апострофы. Внутри апострофов можно написать любое количество произвольных символов - именно они (без обрамляющих апострофов) будут определять новую надпись на кнопке.

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

    К оглавлению

Некоторые итоги

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

  1. Процесс создания Delphi-программы разбивается на две фазы: фазу конструирования формы и фазу кодирования.
  2. Конструирование формы осуществляется с помощью выбора компонентов из палитры и размещения их на форме.
  3. Программист может перемещать любой размещенный на форме компонент и изменять его размеры с помощью мыши.
  4. Чтобы придать компоненту нужные свойства, используется страница Properties Инспектора объектов.
  5. Чтобы компонент мог откликаться на то или иное событие, программист должен создать обработчик события и указать его имя на странице Events Инспектора объектов.
  6. Обработчик события оформляется в виде процедуры, имеющей составное имя. Первая часть имени представляет собой имя класса для формы, вторая часть отделяется от первой точкой и может быть произвольной. Если Delphi автоматически формирует заготовку для обработчика, то вторая часть имени представляет собой объединение имени компонента и имени события без предлога On.
  7. Тело процедуры ограничено словами begin..end и состоит из отдельных предложений (операторов) языка Object Pascal. В конце каждого предложения ставится точка с запятой.
  8. Свойства компонента могут изменяться на этапе выполнения программы.
К оглавлению

    На следующем шаге мы рассмотрим механизм обработки событий с точки зрения Windows.




Предыдущий шаг Содержание Следующий шаг