Генератор исходного кода. Создание простейшего приложения
При работе с компонентами в конструкторе форм Delphi автоматически генерирует соответствующий код на языке Object Pascal. Самый простой метод знакомства с автоматической генерацией кода - начать новый проект, для
этого в главном меню Delphi нужно выбрать команду
File/New/Project (Файл/Новый/Проект). После чего, в конструкторе форм появится новая форма, а в редакторе кода можно видеть уже сгенерированный текст - заготовку будущей программы на языке Object Pascal (листинг 1.1).
Листинг 1.1
unit Unitl;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type
TForml = class(TForm)
private
{ Private declarations }
public
( Public declarations }
end; var
Forml: TForml;
implementation
{$R *.DFM}
end.
Рассмотрим листинг 1.1 более подробно. На нем представлена "заготовка" модуля. В данном случае его название - Unit1. Модуль содержит элементы, которые можно использовать в программе или в других модулях. К числу стандартных модулей среды Delphi относятся такие модули, как system, Sysutiis и др. После компиляции модуля Delphi сохраняет результаты в файле модуля с расширением DCU (Delphi Compiled Unit).
Стандартно, модуль состоит из заголовка и четырех разделов (листинг 1.2).
Листинг 1.2
unit название;
interface
{раздел интерфейса}
uses
{список используемых модулей};
const
{список констант};
type
{описание типов};
var
{объявление переменных};
{заголовки процедур, имеющихся в модуле};
{заголовки функций, имеющихся в модуле};
implementation
{раздел реализации}
uses
{список используемых модулей};
const
{список констант};
type
{описание типов};
var
{объявление переменных};
{описание процедур};
{описание функций};
{директивы препроцессора};
initialization
{раздел инициализации}
{операторы, команды};
finalization
{раздел завершения}
{операторы, команды};
end.
Первый раздел - раздел описания (interface), является как бы "лицом" данного модуля. В нем размещены описания модулей, которые использует модуль, а также в нем объявляются типы, константы, переменные, функции и процедуры, описываются идентификаторы, которые являются доступными всем модулям и программам, использующим данный модуль. Заметим, что для функций и процедур в этом разделе записываются только их заголовки. Непосредственно процедуры и функции размещены в следующем разделе - разделе реализации.
Во втором разделе - разделе реализации (implementation), кроме процедур и функций описываются типы, константы, переменные, а также модули, которые используются только в этом модуле, а за его пределами не видны. Кроме того, в данном разделе размещаются директивы препроцессора - служебные команды среды разработки, например:
{$R *.DFM}.
Директивы препроцессора - это указание компилятору на выполнение каких-либо действий. Их записывают в форме {$ директива}. Директивы препроцессора делятся на глобальные и локальные. Глобальные директивы действуют на весь компилируемый файл, локальные - от места их объявления до появления отменяющей директивы.
Имеются три вида директив: ключевые директивы, директивы параметров и директивы условной компиляции. Первые два вида директив обладают установками по умолчанию. Для установки этих директив вы можете воспользоваться вкладкой
Compiler (Компилятор) диалогового окна
Project Options (Настройки проекта), вызываемого из главного меню Delphi
Project/Options (Проект/Настройки). Для того чтобы посмотреть, какие директивы препроцессора установлены по умолчанию, достаточно, находясь в окне редактора кода, нажать комбинацию клавиш <Ctrl>+<O>, а затем - <О>. В результате, в начале модуля вставятся все значения директив препроцессора, которые используются компилятором в настоящий момент (листинг 1.3).
Листинг 1.3
{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,
N+,0+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
{$MINSTACKSIZE $00004000}
{$MAXSTACKSIZE$00100000}
{$IMAGEBASE $00400000}
($APPTYPE GUI)
Перечислим основные типы директив препроцессора:
- директивы условной компиляции;
- директивы проверки утверждений;
- директивы контроля ввода/вывода;
- директивы, определяющие размер стека;
- директивы информации о типах;
- директивы проверки переполнения при целочисленных операциях;
- директива связывания ресурсов;
- директивы проверки диапазона;
- директива создания консольного приложения.
Директивы условной компиляции позволяют вам управлять компиляцией программного кода. Схема задания условной компиляции может быть двух видов:
{$If условие}
{компилируемый код};
{$EndIf}
И
{$If условие}
{компилируемый код};
{$Else}
{компилируемый код};
{$EndIf}
В обоих случаях, при выполнении некоторого условия, записанного в строке $If, код, расположенный после $If, - компилируется. Иначе, в первом случае - он игнорируется и в результирующий файл не попадает, во втором - выполняется код, записанный после директивы $Else.
Рассмотрим теперь сами условные директивы. Первая директива:
{$IfDef условный идентификатор}
Данная директива проверяет, был ли определен указанный в ней условный идентификатор. Если он был определен, то следующий за ней код будет откомпилирован. Если же директивы, определяющей условный идентификатор, не было, либо она была отменена, то следующий за директивой код откомпилирован не будет.
Для определения условного идентификатора используется директива:
{$Define условный идентификатор}
Для отмены определения условного идентификатора служит директива:
{$UnDef условный идентификатор}
Кроме директивы $IfDef имеется также обратная ей директива $IfNDef.
Она возвращает истинное значение, если указанный в ней условный идентификатор не определен.
Данный вид директив полезен при отладке приложений. Например, программисту часто приходится вводить некоторые промежуточные переменные и объекты, которые необходимы для отладки и не нужны в окончательной версии приложения. Для этого удобно ввести конструкцию вида:
($IfDef Debug}
операторы отладки {$EndIf}
Если в начале программы вы введете директиву
{$Define Debug}
операторы отладки будут компилироваться и выполняться. Но когда вы либо уберете эту директиву, либо закомментируете ее:
//{$Define Debug}
либо введете после нее директиву
{$Undef Debug}
все операторы отладки будут убраны из программы.
Директивы проверки утверждений служат для разрешения или запрещения проверки утверждения. Они влияют на работу процедуры Assert, которая используется при отладке программ. Процедура Assert применяется при от
ладке программ для проверки истинности утверждений, которые по замыслу должны быть истинны, но в силу каких-то ошибок могут нарушаться. Процедура приводит к прекращению работы, генерации исключения EAssertionFaiied и выдаче сообщения об ошибке в случае, если проверяемое утверждение окажется ложным.
Примечание
Информацию об исключительных ситуациях и обработке исключений смотрите во второй главе книги.
Директивы проверки утверждений являются локальными и имеют следующий вид:
{$С+} или ($ASSERTIONS ON}
и
{$С-} или ($ASSERTIONS OFF}
Данная директива действует на весь файл независимо от места своего расположения в нем.
Директивы контроля ввода/вывода служат для включения и выключения контроля работы с файлами. Синтаксис данных директив следующий:
{$I+} или {$IOCHECKS ON}
и
{$I-} или {$IOCHECKS OFF}
При включенной проверке ввода/вывода в файл (директива {$I+} или ($IOCHECKS ON}) в случае возникновения ошибки ввода/вывода генерируется исключение EinOutError. Если действует директива {$I-} или {$IOCHECKS OFF}, то исключение не генерируется.
Директивы, определяющие размер стека, необходимы для задания минимального и максимального размера оперативной памяти, выделяемой под стек. Все локальные переменные процедур и функций размещаются в стеке приложения. При вызове процедуры или функции ее локальные переменные помещаются в стек. При выходе из процедуры или функции локальные переменные удаляются из стека. Директивы препроцессора
{$М минимальный размер стека, максимальный размер стека}
или
($MINSTACKSIZE минимальный размер стека} ($MAXSTACKSIZE максимальный размер стека}
указывают минимальный и максимальный размер стека. Windows гарантированно выделяет приложению область памяти, необходимую для мини
мального размера стека. В случае, если памяти недостаточно, Windows выдаст ошибку при попытке запуска приложения.
Значение минимального размера стека должно находиться в пределах между целыми числами 1024 и 2147483647. Максимальное значение стека должно быть целым числом, расположенным между минимальным размером стека и 2147483647.
В случае нехватки памяти под стек во время работы приложения, размер стека увеличивается на четыре килобайта, при условии, что в данном случае размер стека не превысит максимальный размер. Если размер стека превышает допустимый, генерируется исключение EStackOverflow.
Директивы информации о типах включают или выключают генерацию информации о типах во время выполнения (RunTime Type Information, RTTI). Синтаксис директив:
{$М+} или {$TYPEINFO ON}
и
{$М-} или {$ TYPEINFO OFF}
Директивы проверки переполнения при целочисленных операциях включают или выключают проверку переполнения при выполнении операций над целыми числами (+, -, *, Abs, sqr, Succ, Pred, Inc и Dec). Синтаксис директив:
{$Q+) или {$OVERFLOWCHECKS ON}
и
{$Q-} или {$OVERFLOWCHECKS OFF}
При включенной директиве {$Q+} осуществляется проверка результата вычисления на переполнение. Если переполнение обнаружено, то генерируется исключение EIntOverfiow. Эти директивы проверяют только результаты арифметических операций. Данная директива по умолчанию отключена, т. к. значительно увеличивает размер приложения и замедляет его работу. Целесообразно использовать директиву проверки переполнения при целочисленных операциях на этапе отладки приложения.
Примечание
При отключенной директиве могут появиться ошибки в расчетах, причем сообщений об ошибках не будет.
Директива связывания ресурсов предназначена для связывания файлов ресурсов с исполняемым модулем. Синтаксис директивы:
{$R ресурсы} или {$RESOURCE ресурсы}, где ресурсы - имя или шаблон
файла.
Данная директива указывает файлы ресурсов, имеющие расширение DFM или RES, которые включаются в выполняемый модуль. Заметим, что при генерации заготовки модуля формы (листинг 1.1) Delphi самостоятельно прописывает строку {$R имя-dfm}, которая обеспечивает компоновку файла ресурсов формы.
Примечание
Не удаляйте и не изменяйте строку {$R имя.dfm}, т. к., в данном случае, Delphi не сможет найти файл ресурсов и сгенерируется исключение EResNotFound.
Директивы проверки диапазона предназначены для включения и выключения проверки диапазона целочисленных значений и индексов. Директивы имеют следующий синтаксис:
{$R+} или {$RANGECHECKS ON)
и
{$R-} или {$RANGECHECKS OFF}
Данные директивы, соответственно, включают и выключают проверку диапазона целочисленных значений и индексов. Если включена директива {$R+}, то все индексы массивов и строк и все присваивания скалярным переменным и переменным с ограниченным диапазоном значений проверяются на соответствие значения допустимому диапазону. Если требования диапазона нарушены или присваиваемое значение слишком велико, генерируется исключение ERangeError. Так же, как и директива проверки переполнения, директива {$R+} замедляет работу приложения и увеличивает его размер. Обычно она используется во время отладки приложения.
Директива создания консольного приложения предназначена для указания компилятору того факта, что данное приложение является приложением для DOS. При этом необходимо удалить из проекта все формы и визуальные объекты. Синтаксис директивы:
($APPTYPE CONSOLE}
Примечание
Консольное приложение можно создать и другим способом. Для этого необходимо выполнить команду меню главного окна Delphi
Project/Options (Проект/Настройки) и на вкладке
Linker (Установка связей) установить параметр
Generate Console Application (Создать консольное приложение).
Последние два раздела не являются обязательными. В разделе инициализации (initialization) размещаются операторы и команды, которые должны выполняться в начале работы программы, которая подключает эти модули. При наличии раздела инициализации в модуле может присутствовать раздел
завершения (finalization). В данном разделе находятся операторы и команды, которые выполняются при завершении работы программы.
Содержание раздела