Pascal. ООП. Delphi
Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
A
СОДЕРЖАНИЕ
СОДЕРЖАНИЕ ............................................................................................ A
1. PASCAL ....................................................................................................... 1
1.1 АЛФАВИТ ................................................................................................. 1
1.2 ТИПЫ ДАННЫХ ........................................................................................ 1
1.3 ПЕРЕМЕННЫЕ........................................................................................... 2
1.4 КОНСТАНТЫ............................................................................................. 3
1.5 СТАНДАРТНЫЕ ФУНКЦИИ ........................................................................ 4
1.6 ВЫРАЖЕНИЯ ............................................................................................ 4
1.7 ОПЕРАТОРЫ ............................................................................................. 5
1.7.1 Оператор присваивания ................................................................ 5
1.7.2 Составной оператор ..................................................................... 5
1.7.3 Условный оператор IF .................................................................. 5
1.7.4 Условный оператор CASE ............................................................. 6
1.7.5 Оператор цикла FOR ..................................................................... 7
1.7.6 Оператор цикла REPEAT .............................................................. 8
1.7.7 Оператор цикла WHILE ................................................................ 8
1.8 ОДНОМЕРНЫЕ МАССИВЫ ......................................................................... 9
1.9 МНОГОМЕРНЫЕ МАССИВЫ .................................................................... 11
1.10 СТРОКИ ................................................................................................ 13
1.11 ЗАПИСИ ................................................................................................ 15
1.12 МНОЖЕСТВА ........................................................................................ 17
1.13 ПОЛЬЗОВАТЕЛЬСКИЕ ТИПЫ ................................................................. 18
1.14 ФАЙЛЫ ................................................................................................ 19
1.15 ПЕРЕЧИСЛЯЕМЫЙ ТИП ......................................................................... 21
1.16 ТИП-ДИАПАЗОН ................................................................................... 22
1.17 ФУНКЦИИ И ПРОЦЕДУРЫ ..................................................................... 23
1.18 ЛОКАЛИЗАЦИЯ ИМЕН........................................................................... 26
1.19 МОДУЛИ .............................................................................................. 28
1.20 ОПЕРАТОРЫ ПРЕРЫВАНИЯ ................................................................... 30
1.21 КОММЕНТАРИИ .................................................................................... 31
1.22 УКАЗАТЕЛИ .......................................................................................... 32
1.23 ДИНАМИЧЕСКИЕ МАССИВЫ DELPHI .................................................... 35
2. ОСНОВНЫЕ ПОЛОЖЕНИЯ ООП..................................................... 37
3. БАЗОВЫЕ КЛАССЫ DELPHI ............................................................. 44
3.1 TOBJECT ................................................................................................ 44
3.2 EXCEPTION ............................................................................................. 44
3.3 TLIST ..................................................................................................... 45
3.4 TPERSISTENT .......................................................................................... 46
3.5 TCOLLECTION ........................................................................................ 49
B
3.6 TCOLLECTIONITEM ................................................................................ 49
3.7 TSTRINGS ............................................................................................... 50
3.8 TSTRINGLIST.......................................................................................... 50
3.9 TGRAPHICSOBJECT ................................................................................ 51
3.10 TPEN .................................................................................................... 51
3.11 TBRUSH ............................................................................................... 51
3.12 TCANVAS ............................................................................................. 52
3.13 TGRAPHICS .......................................................................................... 53
3.14 TPICTURE ............................................................................................. 54
3.15 TCOMPONENT ...................................................................................... 54
3.16 TCONTROL ........................................................................................... 54
3.17 TWINCONTROL .................................................................................... 56
3.18 TGRAPHICCONTROL............................................................................. 56
3.19 TTIMER ................................................................................................ 57
3.20 TTHREAD ............................................................................................. 57
3.21 TTREEVIEW ......................................................................................... 58
3.22 TTREENODES ....................................................................................... 59
3.23 TTREENODE ......................................................................................... 59
3.24 TFORM ................................................................................................. 64
3.25 TMAINMENU ....................................................................................... 65
3.26 TMENUITEM......................................................................................... 65
3.27 TSTATUSBAR ....................................................................................... 65
3.28 TSTATUSPANELS .................................................................................. 66
3.29 TSTATUSPANEL.................................................................................... 66
3.30 TTOOLBAR........................................................................................... 66
3.31 TTOOLBUTTON .................................................................................... 67
3.32 TACTIONLIST ....................................................................................... 67
3.33 TACTION .............................................................................................. 67
1
1. PASCAL
1.1 Алфавит
Все символы, используемые в Pascal, можно разбить на 4 группы:
символы, используемые в идентификаторах: буквы 'a''z', 'A''Z'. Нет различий между строчными и прописными буквами; цифры '0''9'; символ подчеркивания '_';
разделители (пробел, символы в диапазоне 031, комментарии);
специальные символы + – * / = , ' . : ; < > [ ] ( ) { } ^ @ $ #;
символы, используемые только в строках символов и комментариях (%, русские буквы).
Идентификатор – имя любого элемента программы. Начинается с буквы или '_'. (63 символа). Целесообразно давать смысловые имена. Многословный: MyProgram, My_Program. Нельзя иметь несколько одинаковых идентификаторов в пределах одного блока. Идентификатор не может совпадать со стандартными функциями и зарезервированными словами.
1.2 Типы данных
Простые типы определяют упорядоченное множество значений параметра.
Порядковые типы отличаются тем, что каждый из них имеет конечное
число возможных значений, которые можно определенным образом упорядочить.
Типы
Простые
Структурированные
Порядковые
Целые
Логические
Символьный
Перечисляемый
Тип-диапазон
Вещественные
Дата-время
Массивы
Записи
Множества
Файлы
Строки
Указатели
Процедурные
Объекты
Варианты
Классы
2
Целые типы различаются диапазоном хранимых значений за счет размера памяти, который они занимают.
Название
Диапазон
Byte
0..255
ShortInt
-128..127
Word
0..65535
Integer
-2147483648..2147483647
LongInt
-2147483648..2147483647
SmallInt
-32768..32767
LongWord 0..4294967295
Int64
-91018.. 91018
Cardinal
0..2147483647
Идентификатору с большим диапазоном значение может быть присвоен
идентификатор с меньшим диапазоном значений, но не наоборот.
Существует несколько логических типов, однако наиболее распространенным является тип Boolean, принимающий значения True либо False (0)
(4<>5).
Символьный тип применяется для описания множества значений символов ПК (Char). Каждому символу присвоен код в диапазоне от 0255. Символы
с кодом 031 являются служебными ('a').
Вещественные типы, строго говоря, тоже имеют конечное множество
значений, однако число таких значений настолько велико, что сопоставить с
каждым порядковый номер не представляется возможным.
Название
Диапазон
Real
5.010-324.. 1.710308
Single
1.510-45.. 3.41038
Double
5.010-324.. 1.710308
Extended 3.410-4951.. 1.1104932
Строковые типы служат, в отличии от символьного, для хранения
групп взаимосвязанных символов. Основным строковым типом является String
('abc'), хранящий до 65 тыс. символов и использующий динамическую память.
Тип ShortString (аналог String в Turbo Pascal) хранит до 255 символов.
1.3 Переменные
Переменными называются параметры программы, значения которых могут измениться в процессе ее выполнения. Все используемые в программе переменные должны быть определены с указанием их типов. Определение производится в разделе var. Формат определения переменных следующий:
<идентификатор1>[,<идентификатор2> …] : <тип>;
3
Пример:
var
A : integer;
B, C : real;
1.4 Константы
Константами называются параметры программы, значения которых не
изменяются в процессе выполнения программы. Константы позволяют сделать
программу более понятной, гибкой при модификации, удобной при отладке.
Определение производится в разделе const. Формат определения констант следующий:
<идентификатор> = <значение>;
Пример:
const
A =
B =
C =
D =
E =
F =
10;
10.0;
10e-7;
'A';
'ABC';
False;
Тип константы определяется по значению, присвоенному идентификатору.
Еще одним типом констант являются типизированные константы,
формат определения которых
<идентификатор> : <тип> = <значение>;
Пример:
const
A : real = 10;
Типизированные константы, в зависимости от настроек Delphi, могут
рассматриваться либо как константы, либо как переменные с начальным значением.
4
1.5 Стандартные функции
Существует ряд функций, выполнение которых заложено в Pascal:
арифметические
Функция
Описание
Тип результата
Abs(X)
абсолютное значение аргумента
тип аргумента
ArcTan(X)
арктангенс
вещественный
Cos(X)
косинус
вещественный
Dec(X[,i])
уменьшение значения на i [1]
целый
x
Exp(X)
e
вещественный
Frac(X)
дробная часть числа
вещественный
Inc(X[,i])
увеличение значения на i [1]
целый
Int(X)
целая часть числа
вещественный
Ln(X)
натуральный логарифм
вещественный
Pi
вещественный
значение
Sin(X)
синус
вещественный
Sqr(X)
возведение в квадрат
тип аргумента
Sqrt(X)
извлечение квадратного корня
вещественный
преобразования
Функция
Описание
Тип результата
Chr(X)
преобразование кода в символ
символьный
Ord(X)
может использоваться для получения целый
кода символа
Round(X)
округление числа
целый
Trunc(X)
получение целой части
целый
XToY
преобразование X в Y, где X и Y : Str, тип части Y
Int, Float, Date, Time, DateTime
работа с порядковыми типами
Функция
Описание
Тип результата
Odd(X)
проверка на нечетность
логический
Pred(X)
предыдущее значение
целый
Succ(X)
следующее значение
целый
1.6 Выражения
Выражения описывают правила получения новых значений. В большинстве случаев выражение состоит из нескольких элементов (операндов) и знаков
операций. В выражении могут участвовать идентификаторы, числовые константы и результаты выполнения функций. Результат выражения определяется
по типу операции и типам входящих в него операндов.
Пример: (a+b)*12, sin(x), a>2.
арифметические операции: +, -, *, /, div, mod;
5
логические операции: not
X
Y
and
or
xor
False False False False False
False True False True True
True False False True True
True True True True False
операции отношений: =, <>, <, >, <=, >=;
круглые скобки.
Порядок вычисления выражений приведен ниже в таблице.
Группа Операции или элементы
1
()
2
функции
3
@, not, унарные операции
4
*, /, div, mod, and
5
+, -, or, xor
6
=, <>, <, >, <=, >=, in
1.7 Операторы
1.7.1 Оператор присваивания
Оператор присваивания выполняет присвоение переменной результата
выражения и записывается в виде :=.
Пример:
a := b*10; {целая или вещественная в зависимости от b}
a := a+1; {целая или вещественная}
a := sqr(sin(b)); { вещественная}
a := b then <выполнять если истина>;
if <условие> then <выполнять если истина> else <выполнять если
ложь>;
Блоки <выполнять если истина> и <выполнять если ложь> являются
одиночным оператором, поэтому часто применяется составной оператор.
Пример (сравнение двух чисел):
procedure TForm1.Button1Click(Sender : TObject);
var
a,b : integer;
s : string;
begin
a := ???;
b := ???;
if a>b then
s := 'А больше В'
else
if a;
end;
1.7.4 Условный оператор CASE
Данный оператор целесообразно использовать для реализации разветвляющегося алгоритма, когда возможно несколько (более 2) вариантов решения.
Формат описания данного оператора:
case <выражение> of
<значение1> : <оператор1>;
<значение2> : <оператор2>;
…
<значениеN> : <операторN>;
else <оператор>;
end;
<выражение> должно быть любого порядкового типа, <значение?> –
любое значение из диапазона данного типа, <оператор?> – выполняемые операторы. Оператор else является необязательным.
Пример (определение дня недели по номеру):
procedure TForm1.Button1Click(Sender: TObject);
var
DayOfWeek : integer;
s : string;
7
begin
DayOfWeek := ???;
case DayOfWeek of
1 : s := 'Это понедельник';
2 : s := 'Это вторник';
3 : s := 'Это среда';
4 : s := 'Это четверг';
5 : s := 'Это пятница';
6 : s := 'Это суббота';
7 : s := 'Это воскресенье';
else s := 'Вы неправильно ввели номер дня недели';
end;
<вывод s>;
end;
1.7.5 Оператор цикла FOR
Данный оператор служит для реализации алгоритмов итерационной
структуры при заранее известном числе итераций. Формат оператора:
for <параметр цикла> := <начальное значение> to
<конечное значение> do <оператор>;
for <параметр цикла> := <конечное значение> downto
<начальное значение> do <оператор>;
<параметр
цикла>, <начальное
значение>, <конечное значение>
должны быть порядкового типа. При этом <начальное значение> должно быть
меньше или равным <конечное значение>, иначе цикл не выполнится ни разу.
Первый вид оператора организует перебор <параметр цикла> с увеличением
на 1, второй – с уменьшением на 1.
Пример (вычисление факториала):
procedure TForm1.Button1Click(Sender: TObject);
var
i,N,F : integer;
begin
N := ???;
F := 1;
for i := 2 to N do
F := F*i;
<вывод F>;
end;
8
1.7.6 Оператор цикла REPEAT
Позволяет организовать итерационный алгоритм в случае, когда заранее
неизвестно число повторений. Формат оператора:
repeat
<операторы>
until <условие>;
Особенностями данного цикла являются:
тело цикла выполняется как минимум один раз;
выход из цикла происходит в случае, если условие выполнено, т.е. цикл
можно трактовать как “пока не выполнится <условие> выполнять тело цикла”;
между ключевыми словами repeat … until нет необходимости вставлять
составной оператор;
в цикле нет “параметра цикла”;
в теле цикла должно быть изменение величин, входящих в условие, иначе
может получиться “вечный цикл”.
Пример (xk/k < a {поиск k}):
var
k : integer;
x,a,p : real;
begin
a := ???;
x := ???;
k := 0;
p := 1;
repeat
inc(k);
p := p*x;
until p/k;
end;
1.7.7 Оператор цикла WHILE
Позволяет организовать итерационный алгоритм в случае, когда заранее
неизвестно число повторений. Формат оператора:
while <условие> do
<оператор>;
Особенностями данного цикла являются:
тело цикла может не выполняться ни разу;
9
выход из цикла происходит в случае, если условие не выполнено, т.е. цикл
можно трактовать как “пока выполняется <условие> выполнять тело цикла”;
в качестве тела цикла выступает один оператор, поэтому при необходимости
выполнения нескольких действий требуется использование составного оператора;
в цикле нет “параметра цикла”;
в теле цикла должно быть изменение величин, входящих в условие, иначе
может получиться “вечный цикл”.
Пример (xk/k < a {поиск k}):
var
k : integer;
x,a,p : real;
begin
a := ???;
x := ???;
k := 1;
p := x;
while p/k>=a do
begin
p :=p*x;
inc(k);
end;
<вывод k>;
end;
1.8 Одномерные массивы
Массив представляет собой фиксированное количество упорядоченных
однотипных компонент, снабженных индексами. Формат определения массива:
<идентификатор1>[, <идентификатор2>…] : array [<тип индекса>] of
<тип компонента>;
Компоненты массива могут быть любого типа, индексы могут быть любого порядкового типа и записываются в формате
<начальный индекс> … <конечный индекс>
В качестве начального и конечного индексов не могут использоваться
переменные (но могут использоваться константы).
Для обращения к компоненту массива требуется указать идентификатор
массива с указанием в квадратных скобках индекса компонента.
Все значения компонентов одного массива можно присвоить компонентам другого массива только в том случае, если эти два массива одного и того же
типа.
10
Для обработки одномерных массивов чаще всего используются итерационные алгоритмы. В приведенном ниже примере рассматриваются стандартные алгоритмы: ввода компонентов, поиска суммы элементов массива, минимального элемента массива, индекса максимального элемента массива, минимального среди положительных чисел массива, сортировки массива, а также
некоторые допустимые и недопустимые действия.
Пример (для пояснения массив 3 7 2 8 1 4 9):
procedure TForm1.Button1Click(Sender: TObject);
var
A,B : array[1..100] of integer;
C : array[1..100] of integer;
n,i,j,k,TempA,MinA,MaxIndexA,SumA : integer;
key : boolean;
const
D : array[1..10] of integer = (1,2,3,4,5,6,7,8,9,10);
begin
n := ???;
for i := 1 to n do
A[i] := ???;
B := A; {Допустимо}
C := A; {Недопустимо}
{Нахождение суммы элементов массива}
SumA := 0;
for i := 1 to n do
SumA := SumA+A[i];
<вывод SumA>;
{Нахождение минимального элемента массива}
MinA := A[1];
for i := 2 to n do
if MinA>A[i] then
MinA := A[i];
<вывод MinA>;
{Нахождение индекса максимального элемента массива}
MaxIndexA := 1;
for i := 2 to n do
if A[MaxIndexA];
{Нахождение минимального из положительных чисел массива}
key := False;
for i := 1 to n do
if A[i]>0 then
if not key then
begin
MinA := A[i];
key := True;
end
else
if MinA>A[i] then
MinA := A[i];
if key then
11
<вывод MinA>
else
<вывод 'Положительных элементов нет'>;
{Сортировка массива по возрастанию}
for i:= 1 to n-1 do
begin
k := i;
for j := i+1 to n do
if A[k]>A[j] then
k := j;
TempA := A[i];
A[i] := A[k];
A[k] := TempA;
end;
for i := 1 to n do
<вывод A[i]>;
{Сортировка массива по убыванию}
i := 1;
while i1 then
dec(i)
else
inc(i);
end
else
inc(i);
for i := 1 to n do
<вывод A[i]>;
end;
1.9 Многомерные массивы
Многомерные массивы отличаются от одномерных заданием нескольких
типов индексов вместо одного, например:
A : array[1..2,1..10,1..5] of integer;
При обращении к компоненту многомерному массиву требуется указать
через запятую индекс компонента по каждой из размерностей. Размерность
массива может быть любой.
При обработке многомерных массивов, в большинстве случаев, требуется применение нескольких вложенных циклов, количество которых определяется размерностью массива.
12
Пример 1 (нахождение минимального элемента массива, подсчет сумм
элементов массива по строкам и столбцам, вывод в табличной форме):
procedure TForm1.Button1Click(Sender: TObject);
var
A : array[1..10,1..10] of integer;
SumCol,SumRow : array[1..10] of integer;
n,m,i,j,MinA : integer;
C : array[1..3,1..3] of integer = ((1,2,3),(4,5,6),(7,8,9));
begin
n := ???;
m := ???;
for i := 1 to n do
for j := 1 to m do
A[i,j] := ???;
{Нахождение минимального элемента массива}
MinA := A[1,1];
for i := 1 to n do
{Обратить внимание на начало с 1 а не с 2}
for j := 1 to m do
if MinA>A[i,j] then
MinA := A[i,j];
<вывод MinA>;
{Подсчет сумм элементов по строкам}
for i := 1 to n do
begin
SumRow[i] := 0;
for j := 1 to m do
SumRow[i] := SumRow[i]+A[i,j];
end;
for i := 1 to n do
<вывод SumRow[i]>;
{Подсчет сумм элементов по столбцам}
for i := 1 to m do
begin
SumCol[i] := 0;
for j := 1 to n do
SumCol[i] := SumCol[i]+A[j,i];
end;
for i := 1 to m do
<вывод SumCol[i]>;
end;
Пример 2 (нахождение наиболее близко расположенных городов, заданных своими координатами):
procedure TForm1.Button1Click(Sender: TObject);
var
A : array[1..100,1..2] of integer;
n,i,j,n1,n2 : integer;
MinA,Temp : real;
begin
n := ???;
for i := 1 to n do
13
for j := 1 to 2 do
A[i,j] := ???;
n1 := 1;
n2 := 2;
MinA := sqrt(sqr(A[n1,1]-A[n2,1])+sqr(A[n1,2]-A[n2,2]));
for i := 1 to n-1 do
for j := i+1 to n do
begin
Temp := sqrt(sqr(A[i,1]-A[j,1])+sqr(A[i,2]-A[j,2]));
if MinA>Temp then
begin
MinA := Temp;
n1 := i;
n2 := j;
end;
end;
<вывод n1 и n2>;
end;
Пример 3 (формирование одномерного массива из положительных чисел):
procedure TForm1.Button1Click(Sender: TObject);
var
A : array[1..10,1..10] of integer;
B : array[1..100] of integer;
Count,n,m,i,j : integer;
begin
n := ???;
m := ???;
for i := 1 to n do
for j := 1 to m do
A[i,j] := ???;
Count := 0;
for i := 1 to n do
for j := 1 to m do
if A[i,j]>0 then
begin
inc(Count);
B[Count] := A[i,j];
end;
for i := 1 to Count do
<вывод B[i]>;
end;
1.10 Строки
Строковый тип String можно рассматривать как одномерный массив
символов. Поэтому обращение к конкретному символу строки можно осу-
14
ществлять по его индексу, например, S[12] – обращение к 12-му символу строки S.
Максимальную длину строки можно задать при объявлении переменной,
например, S : string[80].
Для строк допустимо выполнение операции сложения, например,
S := 'Первая '+'строка'.
Так как каждому символу соответствует определенный числовой код, то
строки можно сравнивать между собой, например, 'AB'>'A' значение True, т.к.
более короткая строка имеет меньший код.
Для работы со строками могут применяться стандартные функции и
процедуры:
Функция
Описание
Length(S)
Определяет длину строки в символах
Pos(SubS,S)
Поиск подстроки SubS в строке S
Copy(S,i,n)
Копирование n символов из строки S начиная с позиции i
Concat(S1[,S2…]) Объединение строк
Delete(S,i,n)
Удаление n символов из строки S начиная с позиции i
Insert(SubS,S,i)
Вставка подстроки SubS в строку S начиная с позиции i
Str(X[:m:n],S)
Перевод числа X в строку S
Val(S,X,c)
Перевод строки S в число X. с – код результата перевода
Пример (разложение строки на отдельные слова):
procedure TForm1.Button1Click(Sender: TObject);
var
S : string;
Mas : array[1..100] of string;
i,n : integer;
begin
S := ???;
n := 0;
repeat
i := Pos(' ',S);
if i>0 then
begin
inc(n);
Mas[n] := Copy(S,1,i-1);
Delete(S,1,i);
end;
until i=0;
if Length(S)>0 then
begin
inc(n);
Mas[n] := S;
end;
for i := 1 to n do
<вывод Mas[i]>;
end;
15
1.11 Записи
В отличии от массива, тип-запись включает ряд компонент, называемых
полями, которые могут быть различных типов. Формат описания:
<идентификатор записи> : record
<идентификатор поля1> : <тип поля1>;
…
<идентификатор поляN> : <тип поляN>;
end;
Количество и тип полей записи может быть произвольным. Для обращения к полю записи используется формат:
<идентификатор записи>.<идентификатор поля>
Если требуется обращение к нескольким полям записи подряд, то можно
для упрощения использовать оператор WITH:
WITH <идентификатор записи> do <оператор>
WITH <идентификатор записи> do
begin
<оператор1>
…
<операторN>
end;
Пример (нахождение среднего роста людей старше 50 лет):
procedure TForm1.Button1Click(Sender: TObject);
var
People : array[1..100] of record
Name : string;
Age : integer;
Height : integer;
end;
i,CountPeople,SumHeight,CountSelect : integer;
begin
CountPeople := ???;
for i := 1 to CountPeople do
begin
People[i].Name := ???;
People[i].Age := ???;
People[i].Height := ???;
end;
CountSelect := 0;
SumHeight := 0;
for i := 1 to CountPeople do
if People[i].Age>50 then
begin
16
inc(CountSelect);
SumHeight := SumHeight+ People[i].Height;
end;
if CountSelect>0 then
<вывод SumHeight/CountSelect>
else
<вывод 'таких людей нет'>;
end;
При работе с записью можно применять вариантную часть, которая может быть одна на всю запись и располагается после описания всех полей:
<идентификатор записи> : record
…
case [<идентификатор поля>:]<тип поля> of
<вариант выбора1> : (<идентификатор поля> : <тип поля>);
…
<вариант выбораN> : (<идентификатор поля> : <тип поля>);
end;
Для всех вариантов отводится общая область памяти, поэтому имеется
возможность преобразовывать данные одного типа в другой, однако при неправильном обращении к полю имеется возможность ошибки.
Пример (нахождение площади фигур):
procedure TForm1.Button1Click(Sender: TObject);
var
Figures : array[1..100] of record
X,Y : real;
case Vid : integer of
0 : (Side : real); {квадрат}
1 : (Side1,Side2 : real){прямоугольник};
2 : (Radius : real); {круг}
end;
Count,i : integer;
s : string;
begin
Count := ???;
for i := 1 to Count do
with Figures[i] do
begin
Vid := ???;
X := ???;
Y := ???;
case Vid of
0 : Side := ???;
1 : begin
Side1 := ???;
Side2 := ???;
end;
2 : Radius := ???;
end;
17
end;
for i := 1 to Count do
begin
with Figures[i] do
case Vid of
0 : s := IntToStr(i)+' - квадрат, S='+
FloatToStr(sqr(Side));
1 : s := IntToStr(i)+' - прямоугольник, S='+
FloatToStr(Side1*Side2);
2 : s := IntToStr(i)+' - круг, S='+
FloattoStr(Pi*sqr(Radius));
end;
<вывод s>;
end;
end;
1.12 Множества
Множества – это наборы однотипных логически связанных друг с другом объектов. Для описания множества используется следующий формат:
<идентификатор> = set of <начало> .. <окончание>
<идентификатор> = set of (<элемент1> [,<элемент2> …])
Элементы, описываемый <начало>, <окончание> должны быть порядкового типа. Количество элементов множества не может превышать 256.
Множества часто используются для проверок установки тех или иных
флагов объектов.
Операции с множествами:
+ – сложение; результат содержит элементы первого множества, дополненные недостающими элементами второго множества;
- – вычитание; результат содержит элементы из первого множества, которые
не принадлежат второму;
* – пересечение; результат содержит элементы, общие для обоих множеств;
= – проверка эквивалентности; возвращается True, если множества эквивалентны;
<> – проверка неэквивалентности; возвращается True, если множества неэквивалентны;
<= – проверка вхождения; возвращается True, если первое множество включено во второе;
>= – проверка вхождения; возвращается True, если второе множество включено в первое;
in – проверка принадлежности; возвращается True, если элемент входит в
множество;
include(s,i) – включает новый элемент i в множество s;
18
exclude(s,i) – исключает элемент i из множество s.
Процедуры include и exclude отличаются высокой скоростью выполнения, т.к. оптимизированы на работу с одиночными элементами.
Рассмотрим на примере операции работы с множествами.
Пример (выполнение действий с множествами):
var
s1,s2,s3,s : set of 0..9;
f : boolean;
begin
s1 := [0..3,6]; {Пример присвоения}
s2 := [4,5];
s3 := [3..9];
s := s1+s2; {s = [0..6] - сложение}
s := s2+s3; {s = [3..9] - отброс дублирования}
s := s1*s3; {s = [3,6] - пересечение}
s := s3-s2; {s = [3,6..9] - вычитание}
f := s1=s2 {f = False}
f := s1<>s2; {f = True}
f := s2<=s3; {f = True}
f := s1>=s3; {f = False}
f := 4 in s1; {f = False}
include(s1,4); {s1 = [0..4,6]}
exclude(s1,2); {s1 = [0..1,3..4,6]}
end;
1.13 Пользовательские типы
При работе со структурированными типами во многих случаях удобнее
при описании переменных, констант использовать заранее созданные пользовательские типы. Формат описания типа:
<идентификатор типа> = <описание типа>;
Описание типов производится в секции type. Вновь созданный тип становится равноправным со стандартными типами, поэтому его использование не
требует отдельного рассмотрения.
Примеры описания типов:
type
Mas = array[1..10] of real;
Matrix = array[1..10,1..10] of integer;
Figure = record
X,Y : real;
case integer of
0 : (Side : real); {квадрат}
1 : (Side1,Side2 : real){прямоугольник};
2 : (Radius : real); {Окружность}
end;
FigureFile = file of Figure;
19
Month = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
Alfa = set of 'A'..'Z';
1.14 Файлы
Файл представляет собой последовательность компонент, размещенных
на внешнем носителе. Для работы с файлами требуется в первую очередь описать переменную, которая будет связана с файлом:
<идентификатор> : {TextFile | file | file of <тип>};
Порядок работы с файлами приведен ниже в таблице (считаем, что имеется переменная f)
Действие
Связывание с переменной
Открытие файла на
чтение
Открытие файла на запись
Чтение
Запись
Закрытие
файла
TextFile
file
AssignFile(f,<имя файла>);
file of …
reset(f);
reset(f[,<число байт>]);
reset(f);
rewrite(f);
rewrite(f[,<число байт>]);
rewrite(f);
read(f,…);
readln(f,…);
write(f,…);
writeln(f,…);
blockread(f, …, <количество>
[,]);
blockwrite(f, …, <количество>
[,<записано>]);
CloseFile(f);
read(f,…);
write(f,…);
При работе с файлами второго типа <число байт> указывает, количество байт, считываемых или записываемых в файл за одну операцию. <количество> указывает на размер чтения или записи в байтах. Для определения этого
параметра можно воспользоваться функцией SizeOf(), в качестве параметра
которой задается тип или идентификатор.
При считывании данных из файла можно воспользоваться функцией
Eof(), которая показывает, был ли достигнут конец файла.
При работе с файлами первого типа возможно использование функции
Append(), открывающую файл на дозапись.
Для файлов второго и третьего типа возможно использование функций
Seek() – смена позиции в файле, FilePos() – определение текущей позиции в
файле, FileSize() – размер файла. Также возможно проведение записи в файл,
открытый с помощью функции Reset(), обеспечивающее модификацию и дозапись файла.
Пример 1 (запись данных о людях в файл различными способами и алгоритм считывания данных из файла):
procedure TForm1.Button1Click(Sender: TObject);
type
MyRec = record
Name : ShortString; // Обратить внимание на ShortString
20
Height : integer;
Weight : real;
end;
var
Mas : array[1..100] of MyRec;
f1 : TextFile;
f2 : file;
f3 : file of MyRec;
i,n : integer;
begin
n := ???;
for i := 1 to n do
begin
Mas[i].Name := ???;
Mas[i].Height := ???;
Mas[i].Weight := ???;
end;
AssignFile(f1,'data.txt');
rewrite(f1);
for i := 1 to n do
begin
writeln(f1, Mas[i].Name);
writeln(f1, Mas[i].Height);
writeln(f1, Mas[i].Weight);
end;
CloseFile(f1);
AssignFile(f2,'data.dat');
rewrite(f2,1);
for i := 1 to n do
begin
blockwrite(f2, Mas[i].Name, SizeOf(Mas[i].Name));
blockwrite(f2, Mas[i].Height, SizeOf(Mas[i].Height));
blockwrite(f2, Mas[i].Weight, SizeOf(Mas[i].Weight));
end;
CloseFile(f2);
AssignFile(f3,'data.rec');
rewrite(f3);
for i := 1 to n do
write(f3, Mas[i]);
CloseFile(f3);
n := 0;
reset(f3);
while not Eof(f3) do
begin
inc(n);
read(f3, Mas[n]);
end;
CloseFile(f3);
end;
21
Пример 2 (обработка файла с множествами):
procedure TForm1.Button1Click(Sender: TObject);
var
fIn,fOut : TextFile;
Processing : set of (DelEndSpace, DelSomeSpace, DelEmptyLine);
s : string;
i : integer;
begin
Processing := [];
if EndSpaceCB.Checked then
Processing := Processing+[DelEndSpace];
if TwoSpaceCB.Checked then
Processing := Processing+[DelSomeSpace];
if EmptyLineCB.Checked then
Processing := Processing+[DelEmptyLine];
AssignFile(fIn,???);
Reset(fIn);
AssignFile(fOut,???);
Rewrite(fOut);
while not Eof(fIn) do
begin
readln(fIn,s);
if DelEndSpace in Processing then
s := Trim(s);
if DelSomeSpace in Processing then
while Pos(' ',s)>0 do
Delete(s, Pos(' ',s,1);
if (s<>'') or ((s='') and
(not(DelEmptyLine in Processing))) then
writeln(fOut,s);
end;
CloseFile(fIn);
CloseFile(fOut);
end;
1.15 Перечисляемый тип
В разделе пользовательских типов тип Month описывает так называемый
перечисляемый тип, формат которого
<идентификатор> = (<элемент1> [,<элемент2> …])
Перечисляемый тип задает множество значений, которые может принимать переменная. Его применение позволяет избежать ошибок выхода переменной за заданные границы и улучшает читабельность программы.
Каждому элементу перечисляемого типа соответствует числовое значение: первому элементу – 0, второму – 1 и т.д.
Пример (определение числа дней в месяцах года):
22
procedure TForm1.Button1Click(Sender: TObject);
type
Months = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
const
DayOfMonth : array[Months] of integer =
(31,28,31,30,31,30,31,31,30,31,30,31);
NameMonths : array[Months] of string =
('январь','февраль','март','апрель','май','июнь',
'июль','август','сентябрь','октябрь','ноябрь','декабрь');
var
Year,n : integer;
i : Months;
begin
Year := ???;
for i := Jan to Dec do
begin
n := DayOfMonth[i];
if i=Feb then
if ((Year mod 4=0) and (Year mod 100<>0)) or
(Year mod 400=0) then
n := 29;
<вывод NameMonths[i]+' - '+IntToStr(n)>;
end;
end;
1.16 Тип-диапазон
Тип диапазон схож с перечисляемым типом, но набор возможных значений задается как диапазон некоторого порядкового типа:
<идентификатор> = <начало> .. <окончание>,
например
type
Less10 = 1..9;
Letter = 'a'..'z';
Как и перечисляемый тип, тип диапазон позволяет избегать выхода значения переменной за границы заданного диапазона.
Для определения минимального и максимального индексов типадиапазона можно воспользоваться функциями Low(X) и High(X), где X – переменная или сам тип.
Пример (определение количества дней в квартале не високосного года):
procedure TForm1.Button1Click(Sender: TObject);
type
Months = (Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec);
First = Jan..Mar;
23
Second = Apr..Jun;
Third = Jul..Sep;
Fourth = Oct..Dec;
NumQuarter = 1..4;
const
DayOfMonth : array[Months] of integer =
(31,28,31,30,31,30,31,31,30,31,30,31);
var
i : Months;
Quarter : NumQuarter;
Sum : integer;
begin
Quarter := ???;
Sum := 0;
case Quarter of
1 : for i := Low(First) to High(First) do
Sum := Sum+DayOfMonth[i];
2 : for i := Low(Second) to High(Second) do
Sum := Sum+DayOfMonth[i];
3 : for i := Low(Third) to High(Third) do
Sum := Sum+DayOfMonth[i];
4 : for i := Low(Fourth) to High(Fourth) do
Sum := Sum+DayOfMonth[i];
end;
<вывод Sum>;
end;
1.17 Функции и процедуры
Процедуры и функции представляют собой относительно самостоятельные фрагменты программы, оформленные особым образом и имеющие идентификатор. Чаще всего они используются для описания повторяющегося фрагмента программы. Отличие функции от процедуры заключается в том, что результатом выполнения функции всегда является некоторое значение, которое
может быть использовано в дальнейшем в выражении.
В дальнейшем будем называть процедуры и функции подпрограммами,
если не требуется уточнение. Формат описания заголовка:
procedure <идентификатор>[(<список формальных параметров>)];
function <идентификатор>[(<список формальных параметров>)] :
<возвращаемый тип>;
<список формальных параметров> может включать любое количество
параметров любых типов. Параметры одного типа можно описывать подряд через запятую. Параметры разного типа при описании отделяются друг от друга
точкой с запятой.
24
Для вызова подпрограммы из основной программы требуется ввести ее
идентификатор и указать фактические параметры, причем их количество и
тип должны в точности соответствовать <списку формальных параметров>.
При описании <списка формальных параметров> каждый из параметров может быть одного из трех типов:
параметр-переменная. Перед описанием такого параметра следует указывать
ключевое слова var. Такой параметр напрямую передаются в подпрограмму,
и его изменение в теле подпрограммы приводит к изменению фактического
параметра, т.е. параметр-переменную можно использовать для возврата в основную программу видоизмененного значения. Параметр-переменная не может быть константой или результатом вычисления выражения;
параметр-значение. При описании такого параметра не требуется ввод уточняющих ключевых слов. При этом, в подпрограмму передается копия фактического параметра, поэтому его изменение в теле подпрограммы не приведет
к смене значения в основной программе. В этом случае фактический параметр может быть константой или результатом вычисления выражения;
параметр-константа. Перед описанием такого параметра следует указывать
ключевое слова const. Такой параметр, как и параметр-переменная, напрямую передаются в подпрограммы, но его изменение в теле подпрограммы
блокируется на стадии компиляции программы. Фактический параметр, как и
для параметра-значения, может быть константой или результатом вычисления выражения.
Так как подпрограммы являются относительно независимыми фрагментами программы, то структура их реализации аналогична структуре программы.
После заголовка могут находиться разделы описания типов, констант, переменных, одна подпрограмма может включать в себя другие подпрограммы, каждая
из которых также может включать в себя другие подпрограммы и т.д. После
описания всех разделов описывается тело подпрограммы путем введения блока
begin … end;.
Подпрограмма может использовать в своей работе и переменные, описанные выше в основной программе, однако этим не стоит злоупотреблять во
избежании появления ошибок и снижения гибкости программы целиком.
При описании тела функции следует указать, какое значение функция
будет возвращать. Это делается путем присвоения идентификатору функции
требуемого значения.
При использовании в качестве параметра подпрограммы массива, следует применять предварительное описание пользовательского типа, например:
type
Mas = array[1..100] of integer;
procedure First(var A : Mas);
Запись procedure First(var A : array[1..100] of integer); недопустима.
25
Однако допустима запись procedure First(var A : array of integer);, в которой происходит использование так называемых открытых массивов, позволяющее передавать подпрограмме массивы переменной длины. Такой
массив трактуется подпрограммой как одномерный массив с начальным индексом 0. Конечный индекс может быть определен с помощью функции High()
(например, High(A)).
В большинстве случаев при передаче в подпрограмму в качестве параметра массива, требуется и передача фактического числа элементов массива,
так как максимальное и текущее количество элементов массива часто различны.
Если в теле подпрограммы требуется использование дополнительных
переменных, то в большинстве случаев целесообразно описание данных переменных именно внутри подпрограммы.
Пример (определение суммы элементов и среднего из положительных
элементов для каждого из двух одномерных массивов):
procedure TForm1.Button1Click(Sender: TObject);
type
Mas = array[1..100] of integer;
var
Mas1,Mas2 : Mas;
Count1,Count2,Sum,i : integer;
Average : real;
function Summa(A : Mas; Count : integer) : integer;
var
i,Sum : integer;
begin
Sum := 0;
for i := 1 to Count do
Sum := Sum+A[i];
Result := Sum;
end;
function AveragePositive(A : Mas; Count : integer;
var Average : real) : boolean;
var
i,CountPositive : integer;
Temp : real; // Объяснить, зачем нужна
begin
CountPositive := 0;
Temp := 0;
for i := 1 to Count do
if A[i]>=0 then
begin
inc(CountPositive);
Temp := Temp+A[i];
end;
if CountPositive>0 then
begin
26
Average := Temp/CountPositive;
Result := True;
end
else
Result := False;
end;
begin
Count1 := ???;
for i := 1 to Count1 do
Mas1[i] := ???;
Count2 := ???;
for i := 1 to Count2 do
Mas2[i] := ???;
Sum := Summa(Mas1,Count1);
<вывод 'Сумма элементов первого массива: '+IntToStr(Sum)>;
Sum := Summa(Mas2,Count2);
<вывод 'Сумма элементов второго массива: '+IntToStr(Sum)>;
if AveragePositive(Mas1,Count1,Average) then
<вывод 'Среднее из положительных элементов первого массива: '+
FloatToStr(Average)>
else
<вывод 'В первом массиве положительных элементов нет'>;
if AveragePositive(Mas2,Count2,Average) then
<вывод 'Среднее из положительных элементов второго массива: '+
FloatToStr(Average)>
else
<вывод 'Во втором массиве положительных элементов нет'>;
end;
1.18 Локализация имен
При использовании подпрограмм возникает возможность использования
в них идентификаторов, которые уже используются в основной программе. Однако при этом требуется четкое представление того, какой из идентификаторов
будет использоваться в том или ином фрагменте программы.
Общим правилом для определения доступности идентификаторов является следующее: доступны всегда идентификаторы, расположенные выше по
описанию и находящиеся в цепочки вложенности процедур и функций. Таким
образом, возможно, например, обращение из процедуры к глобальным переменным основной программы, описанным выше, к переменным других процедур, в которые вложена данная, но невозможно обращение из основной программы к переменным любой из процедур.
Рассмотрим пример:
unit Main;
interface
...
27
implementation
var
A,B : integer;
procedure P1;
var
A,B : integer;
procedure P1_1;
var
A,C : integer;
begin
{Доступные переменные}
A := 1; {переменная процедуры P1_1}
C := 2; {переменная процедуры P1_1}
B := 3; {переменная процедуры P1}
Main.A := 4; {переменная модуля Main}
Main.B := 5; {переменная модуля Main}
{Недоступные переменный}
A из процедуры P1
A,D из процедуры P1_2
E,F из модуля Main
end; {P1_1}
procedure P1_2;
var
A,D : integer;
begin
{Доступные переменные}
A := 1; {переменная процедуры P1_2}
D := 2; {переменная процедуры P1_2}
B := 3; {переменная процедуры P1}
Main.A := 4; {переменная модуля Main}
Main.B := 5; {переменная модуля Main}
{Недоступные переменный}
A из процедуры P1
A,С из процедуры P1_1
E,F из модуля Main
end; {P1_2}
begin
{Доступные переменные}
A := 1; {переменная процедуры P1}
B := 2; {переменная процедуры P1}
Main.A := 3; {переменная модуля Main}
Main.B := 4; {переменная модуля Main}
{Недоступные переменный}
A,С из процедуры P1_1
A,D из процедуры P1_2
E,F из модуля Main
end; {P1}
var
E,F : integer;
28
begin
{Доступные переменные}
A := 1; {переменная модуля
B := 2; {переменная модуля
E := 3; {переменная модуля
F := 4; {переменная модуля
{Недоступные переменный}
A,B из процедуры P1
A,С из процедуры P1_1
A,D из процедуры P1_2
end. {модуля Main}
Main}
Main}
Main}
Main}
Таким образом, в передах видимости оказываются только переменные,
описанные выше в основной программе, либо в текущей процедуре.
1.19 Модули
Во многих случаях, при разработке программ, размещение некоторой
части переменных, констант, функций целесообразно проводить в модулях
(например, библиотека функций).
Модуль – это автономно компилируемая программная единица, включающая в себя различные компоненты интерфейсного раздела, и, возможно,
некоторые исполняемые операторы инициирующего раздела. Реализация процедур и функций модуля описывается в исполняемом разделе.
Каждый модуль описывается в отдельном файле. Формат модуля:
unit <идентификатор модуля>;
interface
<описание типов, констант, переменных, подпрограмм>
implementation
<реализация предоставляемых модулем подпрограмм, описание
локальных типов, констант, переменных, подпрограмм>
[begin
<раздел инициализации>]
end.
<идентификатор модуля> должен совпадать с именем файла, в котором
хранится данный модуль.
Все компоненты, описанные в разделе interface, являются доступными
для всех программ и модулей, использующих данный модуль.
При описании подпрограмм, в разделе interface приводится только заголовок подпрограммы. В разделе implementation заголовок каждой из подпрограмм повторяется, после чего происходит описание ее реализации. При повторении заголовка допускается опускание параметров подпрограммы. Если
параметры не опускаются, то заголовок должен в точности соответствовать заголовку раздела interface.
29
Раздел инициализации, чаще всего, используется для задания начальных
значений переменных, описанных в модуле. Выполнение данного раздела производится только один раз, даже если в разрабатываемой программе имеется
несколько ссылок на данный модуль.
Примечание: в среде Delphi раздел инициализации можно начать используя ключевое слово initialization. Кроме того, после данного раздела
может идти раздел завершения (ключевое слово finalization).
Для подключения модуля к основной программе, а также для использования одним модулем другого, применяется ключевое слово uses, после которого указывается список идентификаторов подключаемых модулей.
При использовании одного модуля другим, подключение модулей с использованием ключевого слова uses может производиться как в разделе
interface, так и в разделе implementation. Однако не допускается взаимное
подключение модулей через разделы interface. При необходимости взаимного подключения модулей, как минимум одно из подключений должно располагаться в разделе implementation. Выбор вариантов подключения производится
на основе того, в каком из модулей необходим доступ к ресурсам другого модуля в разделе interface. В случае, когда обоим модулям требуется подключение в разделе interface, создается третий модуль, в который переносятся
взаимно-зависимые части.
Являясь независимой программной единицей, модуль имеет свое пространство идентификаторов. Если в программе или модуле, использующем
другой модуль, имеется одноименный идентификатор, то ему отдается предпочтение. Для обращения к идентификатору подключаемого модуля, в этом случае, требуется уточнение, записываемое как:
<идентификатор модуля>.<идентификатор компонента>
Пример:
unit Modul1;
interface
type
Mas : array[1..100] of integer;
var
X : integer;
procedure InputMas(var A : Mas; n : integer);
implementation
procedure InputMas(var A : Mas; n : integer);
begin
...
end;
begin
X := 1;
end.
program Program1;
uses Modul1;
30
type
Mas : array[1..100] of integer;
var
X,n : integer;
A : Mas;
B : Modul1.Mas;
begin
...
InputMas(A,n); {Ошибка}
InputMas(B,n); {Нет ошибки}
X := 5; {Иcпользуется переменная основной программы}
Modul1.X := 10; {Используется переменная модуля}
...
end.
1.20 Операторы прерывания
В Pascal имеется четыре оператора, позволяющие прервать выполнение
текущего блока: continue, break, exit, halt(X). Первый из них позволяет
прервать выполнение тела цикла и перейти к следующей итерации, второй –
немедленно закончить выполнение цикла, третий – немедленно выйти из текущего блока (если текущим блоком является основная программа, то закончить
выполнение программы), четвертый – немедленно выйти из программы, при
этом в качестве параметра задается целое значение кода выхода, которое может
быть проанализировано внешней программой, запустившей данную.
2i
i x
Пример 1 (найти первое i, при котором (1)
меньше заданного числа e):
(2i)!
procedure TForm1.Button1Click(Sender: TObject);
var
i,j : integer;
x,Sum,F,S,R,E : real;
begin
x := ???;
E := ???;
i := 1;
Sum := 0;
repeat
F := 1;
for j := 2 to 2*i do
F := F*j;
if odd(i) then
S := -1
else
S := 1;
R := S*exp(2*i*ln(x))/F;
if R=0 then
Continue;
s := 'Первое отрицательное число: '+IntToStr(A[i]);
Break;
end;
<вывод s>;
end;
1.21 Комментарии
Комментарии вводятся в программу для описания ее блоков или отдельных операторов. Использование комментариев позволяет облегчить разбор исходного текста программы для людей, не являющихся ее разработчиками, а
также быстрее вспомнить разработчику идеи, используемые в программе, если
он долго к ней не обращался. Также комментарии могут использоваться для
временного отключения некоторых фрагментов программ при отладке.
Существует три типа комментариев:
пара {} – при обнаружении в программе символа { компилятор считает
комментарием все, что будет расположено до символа };
пара (* *) – при обнаружении в программе комбинации символов (* компилятор считает комментарием все, что будет расположено до комбинации
символов *);
пара // – при обнаружении в программе пары символов // компилятор считает комментарием все, что будет расположено далее в этой строке.
32
Таким образом, первые два типа комментариев позволяют считать комментариями несколько строк, тогда как третий тип комментирует только часть
строки.
Внутри одного комментария может располагаться комментарий другого
типа. При этом, на работу исходного комментария он не оказывает никакого
влияния.
1.22 Указатели
При работе со статическими переменными может возникнуть ситуация,
когда места, отведенного под хранение данных окажется недостаточно для решаемой задачи (Borland Pascal). Одним из способов увеличения объема доступной памяти может быть разделение программы на модули, каждый из которых
имеет свой сегмент данных. Однако наиболее кардинальным решением является использование в программе динамически выделяемой памяти и указателей.
В отличии от статической переменной, в переменной-указателе хранятся
не сами данные, а адрес (указание) места, где их можно найти (привести графическую интерпретацию). Указатели бывают нетипизированные и типизированные. Для обозначения первых служит зарезервированный тип pointer, для вторых – значок “^” с указанием типа, например:
Чтобы указать, что переменная-указатель не ссылается на ячейку памяти, используется ключевое слово nil;
var
p : pointer;
pI1, pI2 : ^integer;
pD : ^double;
I1, I2 : integer;
D : double;
begin
I1 := 5;
I2 := 7;
D := 5.4;
pI1 := addr(I1);
pI2 := addr(I2);
pD := addr(D);
pI1^ := 10; {I1 = 10}
pI2^ := 12; {I2 = 12}
pD^ := 6.7 {D = 6.7}
pI1 := pI2;
pI1^ := 16; {I2 = 16};
p := pI1; {p ссылается на I2}
pD := p; {pD ссылается на I2, что допустимо, но может привести
к ошибке}
pD := pI2; {ошибка, так как указатели типизированные}
p := nil; {указатель p теперь никуда не указывает}
end.
Таким образом, использование типизированных указателей может
предотвратить ошибки, но снижает гибкость программы.
33
Использование указателей наиболее оправданно при работе со сложными структурами с применением динамического выделения памяти. Для выделения памяти и ее освобождения могут быть использованы пары New – Dispose,
GetMem – FreeMem с применением SizeOf.
procedure New(var p : pounter)
procedure Dispose(var p : pointer)
procedure GetMem(var p : pointer; Size : integer)
procedure FreeMem(var p : pointer; Size : integer)
function SizeOf(X) : integer
Приведение типов:
type
PInteger = ^integer;
var
i : integer;
p : pointer;
begin
i := 7;
p := addr(i);
pinteger(p)^ := 12; {i = 12}
integer(p^) := 14; {i = 14}
end.
Пример 1 (работа с памятью при обработке одномерных массивов):
type
PMas = ^Mas;
Mas = array[1..10] of integer;
var
p1, p2 : PMas;
n : integer;
begin
New(p1);
n := 5;
GetMem(p2, SizeOf(integer)*n);
…
p2^[3] := 5;
…
Dispose(p1);
FreeMem(p2, SizeOf(integer)*n);
end.
Пример 2 (работа с памятью при обработке многомерных массивов на
примере упорядочивания столбцов матрицы, вариант 1):
type
PMas = ^Mas;
Mas : array[1..1] of integer;
var
n,m,i,j,Temp : integer;
Data : PMas;
begin
n := ???;
34
m := ???;
GetMem(Data,SizeOf(integer)*n*m);
for i := 1 to n do
for j := 1 to m do
Data^[(i-1)*m+j] := ???;
for j := 1 to m do
begin
i := 1;
while i1 then
dec(i)
else
inc(i)
end
else
inc(i);
end;
for i := 1 to n do
for j := 1 to m do
<вывод Data^[(i-1)*m+j]>;
FreeMem(Data,SizeOf(integer)*n*m);
end;
Пример 3 (работа с памятью при обработке многомерных массивов на
примере упорядочивания столбцов матрицы, вариант 2):
type
PMas1 = ^Mas1;
Mas1 = array[1..1] of integer;
PMas2 = ^Mas2;
Mas2 := array[1..1] pf PMas1;
var
Data : PMas2;
n,m,i,j,k,MaxI,Temp : integer;
begin
n := ???;
m := ???;
GetMem(Data,SizeOf(PMas1)*n);
for i := 1 to n do
GetMem(Data^[i],SizeOf(integer)*m);
for i := 1 to n do
for j := 1 to m do
Data^[i]^[j] := ???;
for j := 1 to m do
begin
for k := 1 to n-1 do
begin
MaxI := k;
35
for i := k+1 to n do
if Data^[i]^[j]>Data^[MaxI]^[j] then
MaxI := i;
Temp := Data^[k]^[j];
Data^[k]^[j] := Data^[MaxI]^[j];
Data^[MaxI]^[j] :=Temp;
end;
end;
for i := 1 to n do
for j := 1 to m do
<вывод Data^[i]^[j]>;
for i := 1 to n do
FreeMem(Data^[i],SizeOf(integer)*m);
FreeMem(Data,SizeOf(PMas1)*n);
end.
(Дать графическую интерпретацию для всех типов работы с памятью)
1.23 Динамические массивы Delphi
Рассмотренная выше работа с динамическими массивами значительно
упрощается в среде Delphi, где такие массивы описываются как
<идентификатор> : array [ of array …] of <тип элемента массива>
Выделение памяти для таких массивов производится с помощью оператора SetLength следующим образом
SetLength(<идентификатор >,<количество элементов>[,<количество
элементов> …])
Используя повторно данную функцию можно увеличить или уменьшить
размерность массива без потери данных.
Освободить память, занятую массивом, можно используя то же оператор
SetLength, указав нулевое количество элементов, либо с помощью команды
<идентификатор> := nil;
Примечание: присвоение значения nil освобождает память только у
динамических массивов Delphi. Для обычных указателей освобождение памяти не производится, что может привести к так называемой “утечке” памяти.
Пример (разбиение строк текстового файла на отдельные слова):
var
Data : array of string;
Data2 : array of array of string;
f : TextFile;
n,m,k,i : integer;
begin
AssignFile(f,???);
36
reset(f);
n := 0;
while not EOF(f) do
begin
inc(n);
SetLength(Data,n);
readln(f,Data[n-1]);
end;
CloseFile(f);
SetLength(Data2,n);
for i := 1 to n do
begin
m := 0;
while Pos(' ',Data[i-1])>0 do
begin
inc(m);
SetLength(Data2[i-1],m);
k := Pos(' ',Data[i-1]);
Data2[i-1,m-1] := Copy(Data[i-1],1,k-1);
Delete(Data[i-1],1,k);
end;
if Data[i-1]<>'' then
begin
inc(m);
Data2[i-1,m-1] := Data[i-1];
end;
end;
...
SetLength(Data2,0,0);
Data := nil;
end.
37
2. ОСНОВНЫЕ ПОЛОЖЕНИЯ ООП
Развитие ООП обусловлено рядом причин. Одна из них – увеличение
сложности программного обеспечения, вызванное:
сложностью предметной области – затрагивание все более широких областей
реальности приводит к тому, что понять целиком систему становится все
труднее. Кроме того, пользователю все труднее объяснить разработчику в
доступной форме, что он хочет. Дополнительную сложность вызывает внесение корректировок в разрабатываемый проект. Применение ОО подхода
снижает данную сложность;
трудностью управления процессом разработки – современные программные
продукты могут содержать миллионы строк кода на языке высокого уровня,
разобраться в которых одному человеку невозможно. Поэтому разработкой
занимается группа разработчиков, между которыми необходимо четкое взаимодействие для поддержания единства и целостности разработки. Разбиение проекта на отдельные модули, формирование иерархии классов объектов
способствует этому;
необходимостью обеспечивать достаточную гибкость программы – в программной индустрии почти нет стандартов, поэтому разработчик, как правило, создает сотни мелких базовых блоков, из которых строится программа
более высокого уровня. При этом в эти блоки, зачастую, закладывается
больший, чем требуется в настоящий момент, объем возможностей для обеспечения гибкого видоизменения системы в дальнейшем;
неудовлетворительным способом описания поведения больших дискретных
систем – в каждый момент времени система находится в определенном дискретном состоянии, характеризуемом текущими значениями переменных, их
адресов, адресов стека и т.д. Однако возможен переход из одного дискретного состояния в другое, не учтенное разработчиком, в котором возможен крах
системы. Разбиение сложной системы на части, их отдельное описание и тестирование, организация как можно меньшего числа каналов взаимодействия
между составными частями позволяет уменьшить вероятность краха системы.
На преодоление этих сложностей и было направлено постепенное изменение языков программирования, основные поколения которых характеризуются:
1 поколение, начало 2: FORTRAN, COBOL – имеют простую структуру, состоящую из глобальных данных и подпрограмм. Так как область данных доступна всем подпрограммам, то ошибка в одной из них может иметь далеко
идущие последствия. Наличие большого числа перекрестных связей между
подпрограммами постепенно приводит к трудности в схемах управления и
при поиске ошибок;
конец 2 и начало 3 поколения – появление средств передачи параметров
между подпрограммами, вложенности подпрограмм, определение областей
видимости, возможность использовать подпрограммы как готовые блоки;
38
конец 3 поколения: FORTRAN II –появление модулей. Однако нет четких
интерфейсов модулей и имеется возможность вызова подпрограммы с несоответствующими параметрами. Сохраняется возможность совместного использования общей области данных модулей;
ООЯ: основа – модуль, составленный из логически связанных классов и объектов. “Объект – сущность, объединяющая процедуры и данные, производящая вычисления и сохраняющая свое локальное состояние”. При объектном
подходе акцент переносится на конкретные характеристики физической или
абстрактной системы. Объекты может только менять состояние, вести себя,
управляться или становиться в определенное отношение к другим объектом.
Свойства, характеризующие объект и его поведение остаются неизменными,
и это должны учитывать другие объекты. Поэтому взаимодействие, в основном, осуществляется через методы объектов, и уменьшена или отсутствует
область глобальных данных.
Объектно-ориентированное программирование – это методология программирования, основанная на представлении программы в виде совокупности
объектов, каждый из которых является экземпляром определенного класса, а
классы образуют иерархию наследования.
Описание класса объектов в среде Delphi осуществляется следующим
образом:
<имя класса> = class[<имя класса-родителя>]
constructor Create;
destructor Destroy; override;
private
aValue : integer;
aData : array[1..10] of double;
procedure SetValue(NewValue : integer);
procedure SetData(Index : integer);
function GetData(Index : integer) : double;
…
protected
…
public
property Value : integer read aValue write SetValue default 0;
property Data[Index : integer] : double read GetData write SetData; default;
…
published
…
end;
Основные концептуальная база ОО стиля – объектная модель, имеющая
четыре главных элемента: абстрагирование, инкапсуляция, модульность,
иерархия.
Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко
определяя его концептуальные границы с точки зрения наблюдателя.
39
Пример – кошка со стороны домашней хозяйки и ветеринара.
Пример: теплица с датчиками температуры, влажности, освещения и т.д.
Датчик характеризуется месторасположением, а также контролируемым значением, которое он по запросу должен возвращать.
TCustomSensor = class
constructor Create(InitX, InitY, InitZ : word);
private
…
public
property X : word read aX;
property Y : word read aY;
property Z : word read aZ;
property Value : double read aValue;
end;
Будем называть объект, использующий ресурсы другого объекта, клиентом, а объект предоставляющий ресурсы – сервером. В этом случае сервер
несет на себе ряд обязательств перед клиентом (в нашем примере: возможность
дать информацию о месте расположения датчика и значении контролируемого
параметра). Однако и клиент обязан требовать от сервера только то, что сервер
может предоставить. Такие взаимоотношения объектов называются контрактной моделью. При нарушении контракта одной из сторон возникает исключительная ситуация, которая может быть обработана специальным образом как
самими участниками контракта, так и третьим объектом.
Инкапсуляция – это процесс отделения друг от друга элементов объекта, определяющих его устройство и поведение; инкапсуляция служит для того, чтобы изолировать контрактные обязательства абстракции от их реализации.
Инкапсуляция обеспечивает принцип, что никакая часть сложной системы не должна зависеть от внутреннего устройства какой-либо другой части.
Инкапсуляция помогает легко перестраивать отдельные части системы и разбивать работу над системой среди коллектива разработчиков.
Пример: введение нагревателей. Пусть в теплице помимо различных
датчиков имеются устройства поддержания климата, одно из которых – нагреватели, расположенные в различных местах и подключенные к различным портам управляющей машины.
THeater = class
…
private
…
protected
Port : integer;
procedure OnOff(NewIsOn : boolean);
public
property X : word read aX;
property Y : word read aY;
property Z : word read aZ;
40
property IsOn : boolean read aIsOn write OnOff;
end;
Используемый для включения и выключения метод OnOff посылает в
порт машины с индексом Port соответствующий сигнал, например
procedure THeater.OnOff(NewIsOn : boolean);
begin
if NewIsOn and (not aIsOn) then
begin
SetPort(Port, True);
aIsOn := True;
end
else
if (not NewIsOn) and aIsOn then
begin
SetPort(Port, False);
aIsOn := False;
end;
end;
Предположим, что произошла смена нагревателей, и теперь вместо посылки сигнала в последовательные порты необходимо заносить команду в какую-либо ячейку памяти. В этом случае для разработчика, использующего объект THeater ничего не меняется, так как поменяется только скрытая от него
часть объекта (например, метод OnOff).
Модульность – это свойство системы, которая была разложена на
внутренне связанные, но слабо связанные между собой модули.
Модульность в чем то аналогична инкапсуляции, т.к. также позволяет
скрыть реализацию тех или иных объектов, полностью некоторые объекты и
разделить разработку сложной системы между коллективом разработчиков или
даже различными компаниями.
В отличии от структурного программирования, где в модули группировались подпрограммы по общности назначения или принципу взаимного использования, в ООП модули строятся по принципу физического разделения
классов и объектов, составляющих логическую структуру проекта. При этом в
пределах одного модуля классы и объекты должны быть тесно связаны.
Особое внимание при разделении проекта на модули должно уделяться
интерфейсной части. Эта часть проекта, как правило, подвержена наименьшим
изменениям, так как внесение изменений в нее влечет изменение во всех элементах проекта, использующих данный модуль. Поэтому следует стремиться к
тому, чтобы интерфейсная часть модулей была возможно более узкой, в пределах обеспечения необходимых связей. Доступ же к данным, размещенным в
модуле, должен осуществляться, по возможности, только через методы модуля,
что исключает возможность несогласованного их изменения.
Иерархия – это упорядочивание абстракций, расположение их по уровням.
41
В Delphi основным видом иерархии является концепция наследования,
которая заключается в том, что “потомок” заимствует структурную и функциональную часть “родителя”. При этом “потомок” может достраивать или переписывать компоненты “родителя”.
Пример: активный датчик.
type
TCustomActiveSensor = class(TCustomSensor)
private
…
procedure Activate; virtual;
procedure Control;
public
property ControlValue : double read aControlValue write
SetControlValue;
property Delta : double read aDelta write SetDelta;
end;
procedure TCustomActiveSensor.Control;
begin
if abs(Value-ControlValue)>Delta then
Activate;
end;
type
TTemperatureSensor = class(TCustomActiveSensor)
private
…
procedure Activate; override;
public
end;
TLigthSensor = class(TCustomActiveSensor)
private
…
procedure Activate; override;
public
end;
…
var
ActiveSensor : TCustomActiveSensor;
TemperatureSensor : TTemperatureSensor;
LigthSensor : TLigthSensor;
begin
…
ActiveSensor := TemperatureSensor;
ActiveSensor.Activate;
ActiveSensor := LigthSensor;
ActiveSensor.Activate;
TemperatureSensor := ActiveSensor; (недопустимо присваивание ро-
42
дителя потомку)
TemperatureSensor := LigthSensor; (не находятся в состоянии подчиненности)
…
end.
Виртуальные методы “родителя” и “потомка” должны иметь одинаковый набор параметров, при этом у “потомка” вместо директивы “virtual” необходимо использовать “override”. Если будет применено директивы “virtual”, то
произойдет скрытие метода “родителя” и будет дано предупреждение об этом.
В случае разумного скрытия метода “родителя” данное предупреждение можно
подавить директивой “reintroduce”.
(Привести графическую интерпретацию таблицы виртуальных методов).
Здесь полиморфизм – одно и то же имя может означать объекты разных классов, но имея общего предка, все они имеют общее подмножество операций, которые можно над ними выполнять.
Таким образом наиболее общие абстракции создают систему базовых
классов, от которой происходит развитие всей системы.
Операторы работы с классами:
as – оператор приведения, позволяющий присвоить объект одного класса переменной другого класса. В приведенном выше примере, например, возможно присвоение следующего вида
TemperatureSensor := ActiveSensor as TTemperatureSensor.
Применение as расширяет диапазон возможностей программиста, однако в этом случае ответственность за правильность работы возлагается на него.
Примером использования данного оператора является работа с элементами
коллекций.
is – оператор проверки класса. Результатом выполнения данного оператора будет логическое значение, например, результатом выполнения
TemperatureSensor is TTemperatureSensor будет True.
Данный оператор используется для определения действительного класса
объекта в том случае, если объект передан через переменную произвольного
класса, например общего для нескольких объектов родителя.
Перегруженные методы.
Перегрузка методов позволяет использовать одно и то же имя метода
для описания более одного метода. При этом, методы должны отличаться набором параметров, а после каждого из методов используется ключевое слово
“overload”. Например, можно реализовать функцию деления отдельно для целых и вещественных чисел:
type
TCustomClass = class
public
function Divide(x, y : integer) : integer; overload;
function Divide(x, y : double) : double; overload;
end;
43
function TCustomClass.Divide(x, y : integer): integer;
begin
Result := x div y;
end;
function TCustomClass.Divide(x, y : double): double;
begin
Result := x/y;
end;
Как и в случае с виртуальными методами, при возникновении предупреждения о скрытии родительского метода, его можно подавить директивой
“reintroduce”.
44
3. БАЗОВЫЕ КЛАССЫ DELPHI
3.1 TObject
Класс TObject является исходным предком для всех объектов и компонентов Delphi. Данный класс используется в качестве предка при объявления
классов простых объектов, не использующих возможности копирования
свойств и операции с потоками, а также по умолчанию, если при объявлении
класса не указан никакой предок.
Класс TObject включает описание фундаментального поведения, присущего всем объектам Delphi, необходимого для создания интерфейса методов,
которые обеспечивают:
возможность создания, обслуживания и разрушения объектов путем выделения, инициализации и освобождения памяти, необходимой для работы объекта (например, методы Create, Destroy, Free);
получение информации о классе объекта, а также информации о опубликованных свойствах объекта, доступной во время выполнения программы
(например, методы ClassInfo, ClassName, ClassNameIs, ClassType,
ClassParent, FieldAddress);
обработку сообщений.
Некоторые методы класса TObject используются непосредственно
Delphi, и не могут быть вызваны пользователем. Другие же методы, наоборот
требуют перекрытия в объектах и компонентах – наследниках TObject, имеющих более сложное поведение.
Хотя класс TObject и не является абстрактным классом, обычно объекты
этого класса не создаются.
3.2 Exception
Класс Exception является наследником TObject и предком всех классов
обработки исключительных ситуаций.
Исключительные ситуации генерируются при возникновении ошибок в
программе, например при делении на ноль, ошибке при переводе строки в число и т.д. При этом производится вывод диалогового окна с описанием ошибки.
Прекращение работы программы при этом не производится, прерывается лишь
выполнение текущего блока программы.
По умолчанию, при возникновении исключительной ситуации, начинает
работать блок обработки исключительных ситуаций Delphi. Однако пользователь может включать в программу свои блоки обработки, используя конструкции:
try…except – для анализа исключительной ситуации и описания поведения
при ней;
45
try…finally – для создания обязательно выполняемых блоков, независимо от
наличия исключительной ситуации.
Некоторые свойства и методы класса Exception:
property Message: string; – строка, описывающая исключительную ситуацию;
constructor Create (const Msg: string); – простейший конструктор для создания исключительной ситуации.
Генерацию исключительной ситуации можно произвести с помощью
оператора raise.
В Delphi определено множество классов исключений (EConvertError,
EMathError, EZeroDivide и т.д.). Возможно создание собственных классов исключений.
EAccessViolation
Программа пытается обратиться к не принадлежащей ей
области памяти или использует недействительный указатель
EArrayError
Ошибка при работе с массивами
EConvertError
Ошибка конвертации StrToInt и т.д.
EDivByZero
Целочисленное деление на ноль
EInOutError
Любая ошибка в файловых операциях
EIntError
Любая ошибка при целочисленных вычислениях
EIntOverflow
Целочисленное переполнение
EListError
Неверные действия со списками
EMatchError
Любая ошибка при операциях с плавающей точкой
EOverflow
Вещественное переполнение
EUnderfow
Слишком маленькое вещественное значение
EZeroDivide
Вещественное деление на ноль
3.3 TList
Класс TList является наследником TObject и служит для создания списка
объектов и обеспечивает:
добавление или удаление объектов в листе;
поиск и доступ к объекту в листе;
сортировку объектов.
Некоторые свойства и методы класса TList:
property Capacity: Integer; – определяет максимальное количество элементов
списка, на которые выделена память. Если при добавление нового элемента
количество элементов превысит Capacity, то его значение будет автоматически увеличено;
property Count: Integer; – определяет текущее количество элементов в списке;
property Items[Index: Integer]: Pointer; – позволяет получать доступ к заданному элементу листа;
46
function Add(Item: Pointer): Integer; – добавляет новый элемент в конец списка;
procedure Insert(Index: Integer; Item: Pointer); – добавляет новый элемент в
заданное место списка;
procedure Clear; dynamic; – удаляет все элементы из списка, но не разрушает
их;
procedure Delete(Index: Integer); – удаляет заданный элемент из списка по
номеру;
function Remove(Item: Pointer): Integer; – удаляет заданный элемент из списка
по адресу;
Следует помнить, что при работе со списком требуется осуществлять
операции приведения типов.
Первый элемент списка имеет индекс 0, второй - 1 и т.д.
3.4 TPersistent
Класс TPersistent является наследником TObject и предком всех объектов, не являющихся компонентами, использующих возможности копирования
свойств и операции с потоками. Он обеспечивает:
чтение и сохранение неопубликованных данных в потоке;
средства для присвоения значений свойствам;
средства для копирования содержимого одного объекта в другой.
Некоторыми методами для реализации этих задач являются:
procedure DefineProperties(Filer: TFiler); virtual; – обеспечивает чтение и запись неопубликованных данных из потока, например файла. По умолчанию
при записи записываются в поток значения всех опубликованных свойств, а
при чтении происходит присваивание считанных значений опубликованным
свойствам;
procedure Assign(Source: TPersistent); (Destination.Assign(Source) - обращение) – копирует в Destination свойства из Source. Если в Destination метод Assign не перекрыт и Destination не знает, как копировать свойства из Source, то
вызывается метод AssignTo объекта Source;
procedure AssignTo(Dest: TPersistent); virtual; (Sourse.AssignTo(Destination)) –
копирует в Destination свойства из Source.
Объекты класса TPersistent обычно не создаются.
Пример использования класса:
type
TMyClass1 = class(TPersistent)
public
a : integer;
procedure Assign(Source : TPersistent); override;
procedure AssignTo(Dest : TPersistent); override;
end;
47
TMyClass2 = class(TPersistent)
public
b : integer;
procedure Assign(Source : TPersistent); override;
procedure AssignTo(Dest : TPersistent); override;
end;
TMyClass3 = class(TPersistent)
public
c : integer;
end;
{ TMyClass1 }
procedure TMyClass1.Assign(Source: TPersistent);
begin
if Source is TMyClass1 then
begin
a := (Source as TMyClass1).a;
exit;
end;
inherited Assign(Source);
end;
procedure TMyClass1.AssignTo(Dest: TPersistent);
begin
if Dest is TMyClass1 then
begin
(Dest as TMyClass1).a := a;
exit;
end;
inherited AssignTo(Dest);
end;
{ TMyClass2 }
procedure TMyClass2.Assign(Source: TPersistent);
begin
if Source is TMyClass2 then
begin
b := (Source as TMyClass2).b;
exit;
end;
if Source is TMyClass1 then
begin
b := (Source as TMyClass1).a;
exit;
end;
inherited Assign(Source);
end;
procedure TMyClass2.AssignTo(Dest: TPersistent);
begin
48
if Dest is TMyClass2 then
begin
(Dest as TMyClass2).b := b;
exit;
end;
if Dest is TMyClass1 then
begin
(Dest as TMyClass1).a := b;
exit;
end;
inherited AssignTo(Dest);
end;
var
MyClass11,MyClass12 : TMyClass1;
MyClass21,MyClass22 : TMyClass2;
MyClass31,MyClass32 : TMyClass3;
begin
MyClass11 := TMyClass1.Create;
MyClass11.a := 1;
MyClass12 := TMyClass1.Create;
MyClass21 := TMyClass2.Create;
MyClass21.b := 2;
MyClass22 := TMyClass2.Create;
MyClass31 := TMyClass3.Create;
MyClass31.c := 3;
MyClass32 := TMyClass3.Create;
MyClass12.Assign(MyClass11); // MyClass12.a = 1
// TMyClass1.Assign
MyClass12.Assign(MyClass21); // MyClass12.a = 2
// TMyClass1.Assign - TPersistent.Assign - TMyClass2.AssignTo
MyClass22.Assign(MyClass21); // MyClass22.b = 2
// TMyClass2.Assign
MyClass22.Assign(MyClass11); // MyClass22.b = 1
// TMyClass2.Assign
// MyClass32.Assign(MyClass31);
// TPersistent.Assign - TPersistent.AssignTo – ошибка
// MyClass32.Assign(MyClass11);
// TPersistent.Assign - TMyClass1.AssignTo TPersistent.AssignTo – ошибка
end;
Обычно AssignTo описывается в protected
49
3.5 TCollection
Класс TCollection является наследником TPersistent и служит для создания коллекции из объектов, наследуемых от TCollectionItem. Класс TCollection
похож на TList, однако использование определенного класса объектов в качестве элемента дает ряд преимуществ.
Некоторые свойства и методы класса TCollection:
property Count: Integer; – определяет число элементов в коллекции;
property ItemClass: TCollectionItemClass; – определяет класс элементов по
умолчанию;
property Items[Index: Integer]: TCollectionItem; – обеспечивает возможность
доступа к элементу коллекции по его индексу;
procedure Clear; – удаляет все элементы из коллекции и разрушает их;
constructor Create(ItemClass: TCollectionItemClass); – создание коллекции,
требующее указание класса элемента коллекции;
function FindItemID(ID: Integer): TCollectionItem; – обеспечивает возможность
доступа к элементу коллекции по его идентификатору.
Несмотря на задание класса элемента при создании коллекции, в нее
можно добавлять любой элемент – наследник от TCollectionItem. Однако в этом
случае требуется проверка класса элемента перед извлечением.
Первый элемент коллекции имеет индекс 0, второй - 1 и т.д.
3.6 TCollectionItem
Класс TCollectionItem является наследником TPersistent и служит для создания объектов, которые размещаются в коллекции.
Некоторые свойства и методы класса TCollectionItem:
property Collection: Tcollection; – указывает на коллекцию, в которой находится элемент, и позволяет переносить элемент из одной коллекции в другую;
property ID: Integer; – идентификатор элемента в коллекции. Присваивается
при добавлении элемента в коллекцию и является уникальным для данной
коллекции. Если элемент удаляется из коллекции, то его идентификатор не
может быть больше никому присвоен;
property Index: Integer; – индекс элемента в коллекции, показывающий его
текущее положение;
constructor Create(Collection: TCollection); virtual; – создание элемента коллекции, с указанием коллекции, в которую он помещается. Каждый объект,
наследуемый от TCollectionItem, может располагаться в одной и только одной
коллекции.
За счет наличия у элемента коллекции свойства ID, слежение за элементов коллекции значительно проще, чем за элементом списка.
50
3.7 TStrings
Абстрактный класс TStrings является наследником TPersistent и служит
основой для всех объектов, представляющих собой список строк. Он позволяет:
добавлять и удалять элементы с указанием конкретных позиций;
находить строки и получать к ним доступ;
читать и записывать строки в потоки и файлы;
связывать с каждой строкой какой-либо объект.
Некоторые свойства и методы класса TStrings:
property Count: Integer; – определяет количество строк в списке;
property Objects[Index: Integer]: TObject; – организует доступ к объекту, связанному с конкретной строкой;
property Strings[Index: Integer]: string; – организует доступ к заданной строке;
function Add(const S: string): Integer; virtual; – добавляет строку в конец списка;
function AddObject(const S: string; AObject: TObject): Integer; virtual; – добавляет строку в конец списка и связывает с ней заданный объект;
procedure AddStrings(Strings: TStrings); virtual; – добавляет набор строк в конец списка;
procedure Clear; virtual; abstract; – удаляет все строки из списка и разрушает
связи со всеми объектам;
procedure Delete(Index: Integer); virtual; abstract; – удаляет заданную строку
из списка;
function IndexOf(const S: string): Integer; virtual; – позволяет получить индекс
заданной строки;
function IndexOfObject(AObject: TObject): Integer; – позволяет получить индекс строки, с которой связан заданный объект;
procedure Insert(Index: Integer; const S: string); virtual; abstract; – добавляет
новую строку в заданное место;
procedure InsertObject(Index: Integer; const S: string; AObject: TObject); – добавляет новую строку в заданное место и связывает с ней заданный объект;
procedure LoadFromFile(const FileName: string); virtual; – позволяет загрузить
набор строк из файла;
procedure SaveToFile(const FileName: string); virtual; – позволяет сохранить
набор строк в заданном файле;
Первый элемент списка имеет индекс 0, второй - 1 и т.д.
3.8 TStringList
Класс TStringList является наследником TStrings и позволяет наряду с
функциями предка:
сортировать строки;
проверять дублирование строк;
51
генерировать события при изменении списка строк.
Некоторые свойства и методы класса TStringList:
property Duplicates: TDuplicates; – определяет поведение списка при обнаружении дубляжа строк;
property Sorted: Boolean; – определяет, требуется ли сортировать строки;
procedure Sort; virtual; – вызов сортировки, когда свойство Sorted имеет значение False;
property OnChange: TNotifyEvent; – определяет действия, выполняемые после
изменения списка строк;
property OnChanging: TNotifyEvent; – определяет действия, выполняемые перед изменением списка строк.
3.9 TGraphicsObject
Абстрактный класс TGraphicsObject является наследником TPersistent и
служит базой для объектов, в которые входят графические объекты Windows:
TBrush, TFont и TPen.
Класс TGraphicsObject предоставляет наследникам механизм реагирования на изменение в свойствах графического объекта:
property OnChange: TNotifyEvent; – описывает действия, выполняемые сразу
после изменения свойств графического объекта.
3.10 TPen
Класс TPen является наследником TGraphicsObject и используется для
рисования линий и границ контуров на поверхности рисования TCanvas.
Некоторые свойства и методы класса TPen:
property Color: TColor; – определяет цвет рисования;
property Mode: TPenMode; – определяет способы комбинирования цвета линии с цветом фона;
property Style: TPenStyle; – определяет тип линии (сплошная, штриховая и
т.д.);
property Width: Integer; – определяет ширину линии.
3.11 TBrush
Класс TBrush является наследником TGraphicsObject и используется для
заполнения замкнутых областей.
Некоторые свойства и методы класса TBrush:
property Bitmap: TBitmap; – описывает внешнее изображение, используемое в
качестве образца заполнения;
property Color: TColor; – определяет цвет заполнения;
52
property Style:TBrushStyle; – определяет тип образца заполнения.
3.12 TCanvas
Класс TCanvas является наследником TPersistent и служит базой для создания поверхностей рисования у объектов. Он:
предоставляет объектов TBrush, TFont и TPen;
позволяет рисовать и заполнять линии и контуры;
позволяет выводить текст;
реагировать на изменения в текущем изображении.
Некоторые свойства и методы класса TCanvas:
property Brush: TBrush; – определяет инструмент заполнения;
property Font: TFont; – определяет формат шрифта вывода надписей;
property Pen: TPen; – определяет инструмент рисования линий и контуров;
property ClipRect: TRect; – определяет область рисования. Если вывод изображения происходит за пределами данной области, то эта часть изображения
не выводится;
property CopyMode: TCopyMode default cmSrcCopy; – определяет режим
наложения изображения на поверхность рисования;
property PenPos: TPoint; – определяет текущую позицию инструмента Pen;
procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); – процедура рисования
дуги. X1, Y1, X2, Y2 – область рисования эллипса, X3, Y3, X4, Y4 – координаты
точек, в которые проводятся из центра эллипса воображаемые линии. Пересечение этих линий с эллипсом дает начало и конец дуги. Дуга берется по
направлению против часовой стрелки;
procedure Chord(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); – аналогична дуге,
только соединяет прямой концы дуги;
procedure Pie(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Longint); – аналогично дуге,
только соединяет концы дуги с центром эллипса;
procedure Draw(X, Y: Integer; Graphic: TGraphic); – выводит изображение на
поверхность рисования. X, Y – координаты левого верхнего угла изображения;
procedure StretchDraw(const Rect: TRect; Graphic: TGraphic ); – выводит
изображение на поверхность рисования, вписывая его в заданную область.
procedure Ellipse(X1, Y1, X2, Y2: Integer); – процедура рисования эллипса,
вписанного в прямоугольник X1, Y1, X2, Y2;
procedure FillRect(const Rect: TRect); – процедура построения закрашенного
прямоугольника без границей;
procedure FloodFill(X, Y: Integer; Color: TColor; FillStyle: TFillStyle); – процедура заполнения произвольной области. FillStyle описывает тип заполнения
(граница, цвет);
procedure FrameRect(const Rect: TRect); процедура построения незакрашенного прямоугольника с границей;
53
procedure LineTo(X, Y: Integer); – процедура построения линии из текущей в
заданную точку;
procedure MoveTo(X, Y: Integer); – процедура перемещения текущей точки
рисования;
procedure Polygon(Points: array of TPoint); – процедура построения серии линий с соединение концов;
procedure Polyline(Points: array of TPoint); – процедура построения серии линий без соединения концов;
procedure Rectangle(X1, Y1, X2, Y2: Integer); – процедура построения закрашенного прямоугольника с границей;
procedure RoundRect(X1, Y1, X2, Y2, X3, Y3: Integer); – процедура построения
закрашенного прямоугольника с границей и сглаженными углами. Углы
сглаживаются по эллипсу, вписанному в область X1, Y1, X3, Y3;
procedure TextOut(X, Y: Integer; const Text: string); – вывод текста в заданной
позиции;
function TextHeight(const Text: string): Integer; – получение высоты текста;
procedure TextRect(Rect: TRect; X, Y: Integer; const Text: string); – вывод текста в заданной позиции, но с ограничением по области вывода;
function TextWidth(const Text: string): Integer; – получение ширины текста;
property OnChanging: TNotifyEvent; – определяет действия, выполняемые перед изменением изображения.
3.13 TGraphics
Абстрактный класс TGraphics является наследником TPersistent и служит базовым классом для объектов типа “иконка”, “растровое изображение”,
“метафайлы” c возможностью хранить и показывать изображения. Свойства
класса TGraphics обеспечивают получение информации о состоянии и размерах
изображения.
Для работы с изображением указанных типов используются специализированные классы TBitmap, TIcon или TMetafile. В противном случае используется класс TPicture.
Некоторые свойства и методы класса TGraphics:
property Height: Integer; – определяет высоту изображения;
property Modified: Boolean; – определяет, было ли изображение изменено;
property Transparent: Boolean; – определяет, используется ли прозрачность
изображения;
property Width: Integer; – определяет ширину изображения;
procedure LoadFromFile(const FileName: string); virtual; – загрузка изображения из файла;
procedure SaveToFile(const FileName: string); virtual; – сохранить изображение в файл.
54
3.14 TPicture
Класс TPicture является наследником TPersistent и служит базовым классом для объектов типа “иконка”, “растровое изображение”, “метафайлы”
3.15 TComponent
Класс TComponent является наследником TPersistent и предком всех невизуальных компонентов, который:
позволяет добавить компонент в набор компонентов Delphi и управлять им в
режиме разработки программы;
обеспечивает возможность компоненту включать в себя другие компоненты
и управлять ими;
расширяет возможности по работе с потоками.
Некоторые свойства и методы класса TComponent:
property Name: TComponentName; – описывает имя компонента для обеспечения возможности обращения к нему. Подчиняется всем правилам, применяемым при выборе имен переменных, констант, типов и т.д.;
property Tag: Longint; – свойство, не используемое Delphi. Может применяться, например, для хранения информации о состоянии компонента;
property Owner: TComponent; – позволяет установить владельца данного компонента;
property ComponentIndex: Integer; – определяет положение компонента в
списке компонентов владельца;
property ComponentCount: Integer; – описывает число компонентов, для которых данный компонент является владельцем;
property Components[Index: Integer]: TComponent; – позволяет получить доступ к одному из компонентов, которыми владеет данный компонент, по его
индексу;
function FindComponent(const AName: string): TComponent; – позволяет получить доступ к одному из компонентов, которыми владеет данный компонент,
по его имени;
procedure InsertComponent(AComponent: TComponent); – устанавливает данный компонент владельцем компонента AComponent;
Объекты класса TComponent обычно не создаются.
3.16 TControl
Абстрактный класс TControl является наследником TComponent и предком всех визуальных компонентов. Описывает общие для всех визуальных
компонентов свойства, методы и события. Многие из свойств и методов данно-
55
го класса являются защищенными, а их опубликование происходит в классахпотомках.
Некоторые свойства, методы и события класса TControl:
property Align: TAlign; – задает метод выравнивания компонента в владельце;
property AutoSize: Boolean; – позволяет компоненту корректировать свой
размер в соответствии с содержимым;
property Caption: TCaption;,
property Text: TCaption; – задают текстовые строки для идентификации компонента, например, заголовок, метку. Как правило, у компонента опубликовано только одно из этих свойств;
property ClientHeight: Integer;,
property ClientWidth: Integer;,
property ClientOrigin: TPoint;
property ClientRect: TRect; – определяют размеры и положение области, в которой могут располагаться компоненты, которыми владеет данный компонент;
property Color: TColor; – определяет цвет компонента;
property Enabled: Boolean; – задает, может ли компонент реагировать на
мышь, клавиатуру и события таймера;
property Font: TFont; – определяет шрифт компонента;
property Height: Integer;,
property Left: Integer;,
property Top: Integer;,
property Width: Integer; – определяют размеры и положение компонента во
владельце;
property Parent: TWinControl; – визуальный владелец данного компонента,
т.е. компонент, внутри которого отображается данный компонент. Не следует
путать это свойство со свойством Owner, которое используется, например,
при разрушении объектов.
property PopupMenu: TPopupMenu; – позволяет задать всплывающее меню
для компонента, вызываемое, как правило, при нажатии на компоненте правой (второй) кнопки мыши;
property Visible: Boolean; – задает, видим ли компонент на экране;
procedure Hide; – делает компонент невидимым;
procedure Show; – делает компонент видимым;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); virtual; – задает
размеры и положение компонента внутри владельца;
property OnClick: TNotifyEvent; – определяет действия объекта при нажатии
на нем, например левой (первой) кнопкой мыши;
property OnDblClick: TNotifyEvent; – определяет действия объекта при двойном нажатии на нем левой (первой) кнопкой мыши;
property OnResize: TNotifyEvent; – определяет действия объекта при изменении размера;
property OnMouseDown: TMouseEvent; – определяет действия объекта при
нажатии на нем клавиши мыши;
56
property OnMouseUp: TMouseEvent; – определяет действия объекта при отпускании на нем клавиши мыши;
property OnMouseMove: TMouseMoveEvent; – определяет действия объекта
при перемещении над ним клавиши мыши;
3.17 TWinControl
Абстрактный класс TWinControl является наследником TControl и предком всех визуальных компонентов, которые:
могут получать фокус во время работы приложения;
могут быть присвоены другим компонентам как Parent;
могут иметь заголовок окна – идентификатор окна Windows;
Некоторые свойства, методы и события класса TWinControl:
property BorderWidth: TBorderWidth; – ширина рамки компонента;
property Brush: TBrush; – определяет цвет и тип фона компонента;
property Controls[Index: Integer]: TControl; – позволяет получить доступ к
компоненту, для которого данный компонент Parent;
property TabOrder: TTabOrder; – определяет последовательность перехода от
компонента к компоненту при нажатии клавиши TAB;
property TabStop: Boolean; – указывает, можно ли останавливаться на компоненте при нажатии клавиши TAB;
procedure SetFocus; virtual; – переводит фокус на данный компонент;
property OnKeyDown: TKeyEvent; – определяет действия при нажатии клавиши на клавиатуре (с учетом клавиш Shift, Alt, Ctrl), когда объект имеет фокус;
property OnKeyUp: TKeyEvent; – определяет действия при отпускании клавиши на клавиатуре (с учетом клавиш Shift, Alt, Ctrl), когда объект имеет фокус;
property OnKeyPress: TKeyPressEvent; – определяет действия при нажатии
клавиши на клавиатуре (без учетом клавиш Shift, Alt, Ctrl), когда объект имеет фокус;
3.18 TGraphicControl
Абстрактный класс TGraphicControl является наследником TControl и
предком всех визуальных компонентов, которые не имеют заголовок окна,
например, изображение, метка.
Свойства и методы класса TGraphicControl:
property Canvas: TCanvas; – определяет поверхность на которой производится построение изображения на компоненте;
procedure Paint; virtual; – описывает процедуру построения изображения на
компоненте.
57
3.19 TTimer
Класс TTimer является наследником TComponent и служит для организации потоков команд. Имеет низкий приоритет выполнения.
Свойства, методы и события класса TTimer:
property Enabled: boolean; – включение и выключение таймера;
property onTimer: TNotifiEvent; – процедура, описывающая действия при срабатывании таймера;
property Interval: cardinal; – определяет время (в ms), через которое срабатывает таймер.
3.20 TThread
Абстрактный класс TThread является наследником TObject и служит для
организации потоков команд.
Свойства, методы и события класса TThread:
property FreeOnTerminate: boolean; – указание на саморазрушение при завершении процедуры выполнения;
property Priority: TThreadPriority; – задание приоритета выполнения действий;
property Suspended: boolean; – проверка на паузу в работе потока;
property Terminated: boolean; – указаний на необходимость завершения потока;
constructor Create(CreateSuspended : boolean); – при создании указывается,
требуется ли поток установить в режим “пауза”;
procedure Execute: virtual; abstract; – метод, описывающий действия, которые
должен выполнять поток. Данный метод должен проверять завершение работы потока и прервать свою работу при получении команды “завершение”;
procedure Resume; – запустить после “паузы”;
procedure Suspend; – включить “паузу”;
procedure Synchronize(Method : TThreadMethod); – синхронизация выполнения действий с VCL;
procedure Terminate; – дать команду на завершение работы потока;
Пример работы потока.
TMyThread = class(TThread)
protected
x : integer;
constructor Create(CreateSuspended: Boolean);
procedure Execute; override;
procedure ThreadSyn;
end;
var
MyThread : TMyThread;
58
constructor TMyThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
x := 0;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
x := x+5;
Synchronize(ThreadSyn)
end;
procedure TMyThread.ThreadSyn;
begin
Form1.StaticText1.Caption := IntToStr(x);
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
MyThread := TMyThread.Create(True);
MyThread.FreeOnTerminate := True;
MyThread.Resume;
Button1.Enabled := False;
Button2.Enabled := True;
end;
procedure TForm1.Button2Click(Sender : TObject);
begin
MyThread.Terminate;
Button1.Enabled := True;
Button2.Enabled := False;
end;
3.21 TTreeView
Класс TTreeView является непрямым наследником TWinControl и служит
для создания иерархического списка элементов.
Свойства, методы и события класса TTreeView:
property AutoExpand: boolean; – если установлено, то автоматически раскрывается список для выбранного компонента и закрываются невыбранные;
property Images: TCustomImageList; – задает список изображений, отображаемых в компоненте;
property Items: TTreeNodes; – задает набор элементов компонента, позволяя
обращаться к ним по номеру;
property ReadOnly: Boolean; – определяет, разрешено ли изменение меток
элементов;
property Selected: TTreeNode; – получение или задание выбранного элемента;
59
property ShowButtons: Boolean; – определяет, требуется ли выводить значки
“+” и “-”;
property ShowLines: Boolean; – определяет, требуется ли выводить соединительные линии;
property TopItem: TTreeNode; – получение или установка верхнего видимого
на данный момент элемента;
procedure FullCollapse; – сворачивает всю структуру;
procedure FullExpand; – разворачивает всю структуру;
procedure LoadFromFile(const FileName: string); – считывает структуру из
файла;
procedure SaveToFile(const FileName: string); – сохраняет структуру в файл;
property OnChange: TTVChangedEvent; – позволяет обрабатывать переход от
одной структуры к другой;
3.22 TTreeNodes
Класс TTreeNodes является наследником TPersistent и служит для хранения и управления элементами TTreeView.
Свойства и методы класса TTreeNodes:
property Count: Integer; – описывает количество элементов;
property Item[Index: Integer]: TTreeNode; default; – позволяет получать доступ
к заданному элементу;
function Add(Node: TTreeNode; const S: string): TTreeNode; – добавление нового элемента уровня Node;
function AddChild(Node: TTreeNode; const S: string): TTreeNode; – добавление
нового элемента в подуровень Node;
function AddObject(Node: TTreeNode; const S: string; Ptr: Pointer): TTreeNode;
– добавление нового элемента уровня Node со связанным с ним объектом;
function AddChildObject(Node: TTreeNode; const S: string; Ptr: Pointer
): TTreeNode; – добавление нового элемента в подуровень Node со связанным
с ним объектом;
procedure Clear; – удаление всех элементов;
function GetFirstNode: TTreeNode; – получение первого элемента TTreeView;
function GetNode(ItemId: HTreeItem): TTreeNode; – получение элемента по
уникальному номеру;
3.23 TTreeNode
Класс TTreeNode является наследником TPersistent и служит для описания одного элемента TTreeView.
Свойства и методы класса TTreeNode:
property AbsoluteIndex: Integer; – абсолютный индекс элемента. Если элемент
имеет потомков, то он на один меньше, чем у первого потомка;
60
property Count: Integer; – число прямых наследников элемента;
property Data: Pointer; – связанные с элементом данные;
property Expanded: Boolean; – управляет развертыванием данного элемента;
property HasChildren: Boolean; – указывает, имеет ли элемент потомков;
property ImageIndex: TImageIndex; – номер рисунка в списке рисунков, когда
элемент не выбран;
property SelectedIndex: TImageIndex; – номер рисунка в списке рисунков, когда элемент выбран;
property Index: Longint; – указывает на номер среди потомков;
property Item[Index: Integer]: TTreeNode; – доступ к потомкам;
property ItemId: HTreeItem; – уникальный номер элемента;
property Level: Integer; – указывает на общий уровень элемента;
property Owner: TTreeNodes; – указывает на список элементов, которому
принадлежит данный элемент;
property Parent: TTreeNode; – указывает на родителя;
property Selected: Boolean; – указывает, выбран ли данный элемент;
property TreeView: TCustomTreeView; – указывает, какому TTreeView принадлежит элемент;
procedure Collapse(Recurse: Boolean); – позволяет свернуть выбранный элемент. Если Recurse имеет значение True, то свернуться и все потомки;
procedure Delete; – удаляет элемент и всех его потомков;
procedure DeleteChildren; – удаляет всех потомков элемента;
procedure Expand(Recurse: Boolean); – разворачивает элемент. Если Recurse
имеет значение True, то разворачиваются и потомки;
function GetFirstChild: TTreeNode; – получение первого потомка;
function GetPrevChild(Value: TTreeNode): TTreeNode; – получение предыдущего потомка;
function GetNextChild(Value: TTreeNode): TTreeNode; - получение следующего
потомка;
function GetLastChild: TTreeNode; – получение последнего потомка;
function GetNext: TTreeNode; – получение следующего элемента независимо
от его уровня;
function GetPrev: TTreeNode; – получение предыдущего элемента независимо
от его уровня;
Пример: описание каталога книг по разделам. Каждый раздел имеет
наименование, шифр, список книг. Каждая книга имеет наименование, автора,
количество страниц.
61
type
TBook = class(TCollectionItem)
public
Name,Autor : ShortString;
Count : integer;
end;
TRazdel = class(TCollectionItem)
public
Name,Shifr : ShortString;
Books : TCollection;
constructor Create(Collection: TCollection); override;
destructor Destroy; override;
end;
{ TRazdel }
constructor TRazdel.Create(Collection: TCollection);
begin
inherited Create(Collection);
Books := TCollection.Create(TBook);
end;
destructor TRazdel.Destroy;
begin
Books.Free;
inherited Destroy;
end;
procedure TForm1.AddButtonClick(Sender: TObject);
var
MyTN : TTreeNode;
Razdel : TRazdel;
Book : TBook;
62
TempCol : TCollection;
begin
case TreeView1.Selected.Level of
0 : with RazdelForm do
begin
NameEdit.Text := '';
ShifrEdit.Text := '';
if ShowModal=mrOk then
begin
Razdel := TRazdel.Create(Razdels);
Razdel.Name := Trim(NameEdit.Text);
Razdel.Shifr := Trim(ShifrEdit.Text);
MyTN :=
TreeView1.Items.AddChildObject(TreeView1.Selected,
Razdel.Shifr,Razdel);
TreeView1.Items.AddChild(MyTN,'Раздел: '+Razdel.Name);
TreeView1.Items.AddChildObject(MyTN,'Книги',
Razdel.Books);
end;
end;
2 : with BookForm do
begin
NameEdit.Text := '';
AutorEdit.Text := '';
CountEdit.Text := '';
if ShowModal=mrOk then
begin
TempCol := TCollection(TreeView1.Selected.Data);
Book := TBook.Create(TempCol);
Book.Name := Trim(NameEdit.Text);
Book.Autor := Trim(AutorEdit.Text);
Book.Count := StrToInt(CountEdit.Text);
MyTN :=
TreeView1.Items.AddChildObject(TreeView1.Selected,
Book.Name,Book);
TreeView1.Items.AddChild(MyTN,'Автор: '+Book.Autor);
TreeView1.Items.AddChild(MyTN,'Кол-во страниц: '+
IntToStr(Book.Count));
end;
end;
end;
end;
procedure TForm1.DelButtonClick(Sender: TObject);
begin
TObject(TreeView1.Selected.Data).Free;
TreeView1.Selected.Delete;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Razdels := TCollection.Create(TRazdel);
63
TreeView1.Items.AddObject
(TreeView1.Items.GetFirstNode,'Разделы',Razdels);
end;
procedure TForm1.TreeView1Change(Sender: TObject; Node:
TTreeNode);
begin
if TreeView1.Selected=nil then
begin
Edit1.Text := '';
AddButton.Enabled := False;
end
else
case TreeView1.Selected.Level of
0 : begin
Edit1.Text := 'Это корень нашей структуры';
AddButton.Enabled := True;
end;
1 : begin
Edit1.Text := 'Вы выбрали раздел '+
TreeView1.Selected.Text;
AddButton.Enabled := False;
end;
2 : if TObject(TreeView1.Selected.Data) is TCollection then
begin
Edit1.Text := 'Это список книг раздела '+
TreeView1.Selected.Parent.Text;
AddButton.Enabled := True;
end
else
begin
Edit1.Text := 'Это название раздела '+
TreeView1.Selected.Parent.Text;
AddButton.Enabled := False;
end;
3 : begin
Edit1.Text := 'Это книга '+
TreeView1.Selected.Text+
' из раздела '+TreeView1.Selected.Parent.Parent.Text;
AddButton.Enabled := False;
end;
4 : begin
Edit1.Text := 'Это характеристики книги '+
TreeView1.Selected.Parent.Text;
AddButton.Enabled := False;
end;
end;
end;
64
3.24 TForm
Класс TForm является непрямым наследником TWinControl.
Свойства и события класса TForm:
property BorderIcons:TBorderIcons; – указывает на кнопки, расположенные в
строке заголовка;
property BorderStyle: TFormBorderStyle; – указывает на тип границы и поведение формы
bsDialog – стандартное диалоговое окно, не меняющее размеры, не может
иметь меню;
bsSingle – не меняющее размеры окно с тонкой границей;
bsNone – не меняющее размеры окно без границы;
bsSizeable – стандартное окно с изменяемыми размерами;
bsToolWindow – не меняющее размеры окно с маленьким заголовком;
bsSizeToolWin – меняющее размеры окно с маленьким заголовком;
property Menu: TMainMenu – указатель на меню формы;
property ModalResult: TModalResult – модальный результат, с которым было
закрыто диалоговое окно;
property Visible : boolean; – видима ли форма;
property OnActivate: TNotifyEvent; – событие, возникающее когда форма получает фокус;
property OnDeactivate: TNotifyEvent; – событие, возникающее когда форма
теряет фокус;
property OnClose: TCloseEvent; – событие, когда форма закрывается. Процедура обработки события имеет параметр Action, позволяющий установить
режим закрытия:
caNone – ничего не происходит, отменить закрытие;
caHide – форма не будет закрыта, а просто будет невидима. Остается возможность доступа к этой форме;
caFree – действительно закрыть форму и освободить всю память;
caMinimize – вместо закрытия минимизировать форму;
property OnCloseQuery: TCloseQueryEvent; – обработка данного события позволяет установить, возможно ли закрытие формы в данный момент;
property OnCreate: TNotifyEvent; – возникает после создания формы. Применяется для проведения операций выделения памяти и установки начальных
значений переменных;
property OnDestroy: TNotifyEvent; – возникает перед разрушением формы и
позволяет, например, освободить память;
property OnShow: TNotifyEvent; – возникает в случае, когда происходит перевод формы в видимый режим;
property OnHide: TNotifyEvent; – возникает в случае, когда происходит перевод формы в видимый режим;
65
property OnPaint: TNotifyEvent; – возникает, когда происходит перерисовка
формы. Может применяться для восстановления нарисованного на “канве”
изображения.
3.25 TMainMenu
Класс TMainMenu является непрямым наследником TComponent и служит для создания элементов основного меню программы.
Свойства и события класса TForm:
property Images: TCustomImageList; – указывает на список изображений, применяемых в меню;
property Items: TMenuItem; default; – указывает на список всех элементов меню;
3.26 TMenuItem
Класс TMenuItem является наследником TComponent и служит для создания элементов основного меню программы.
Свойства и события класса TForm:
property Action: TBasicAction; – указание на действие, с которым связан элемент меню;
property Caption: string; – заголовок элемента меню;
property Checked: Boolean; – указывается, отображается ли около заголовка
символ “выбрано”;
property Default: Boolean; – указывает, что двойное нажатие на элементродитель приведет к выполнению данного пункта меню;
property RadioItem: Boolean; – указывает, является ли данный элемент частью
связанных пунктов меню;
property GroupIndex: Byte; – указывает, к какой группе связанных пунктов
меню относится данный элемент;
property Enabled: Boolean; – указывает, доступен ли данный элемент меню;
property ImageIndex: TImageIndex; – указывает на номер рисунка, связанного
с данным элементом меню;
property Visible: Boolean; – указывает, видим ли данный элемент меню;
property OnClick: TNotifyEvent; – вызывается, если произошел выбор данного
элемента меню.
3.27 TStatusBar
Класс TStatusBar является наследником TWinComponent и служит для
создания строки состояния программы.
Свойства и события класса TForm:
66
property Panels: TStatusPanels; – позволяет управлять панелями строки состояния;
property SimplePanel: Boolean; – скрывает все панели и выводит простую панель, занимающую всю строку состояния;
property SimpleText: string; – описывает текст, выводимый в простой панели;
3.28 TStatusPanels
Класс TStatusPanels является наследником TCollection.
Свойства и события класса TForm:
property Items[Index: Integer]: TStatusPanel; default; – позволяет управлять
панелями строки состояния;
property Count: Integer; – описывает число панелей;
3.29 TStatusPanel
Класс TStatusPanel является наследником TCollectionItem.
Свойства и события класса TForm:
property Alignment: TAlignment; – описывает правило выравнивания текста на
панели;
property Bevel: TStatusPanelBevel; – описывает внешний вид панели;
property Text: string; – описывает текст, выводимый в панель;
property Width: Integer; – описывает ширину панели;
3.30 TToolBar
Класс TToolBar является непрямым наследником TWinControl и служит
для создания панелей управления.
Свойства класса TToolBar:
property ButtonHeight: Integer; property ButtonWidth: Integer; – описывают высоту и ширину кнопок;
property Flat: Boolean; – определяет невидимость границ кнопок;
property Images: TCustomImageList; – задает стандартный набор изображений;
property DisabledImages: TCustomImageList; – задает набор изображений, активируемый при запрете использования кнопки;
property HotImages: TCustomImageList; – задает набор изображений, активируемый при помещении мыши над кнопкой;
property Buttons[Index: Integer]: TToolButton; – доступ к кнопкам;
property Indent: Integer; – определяет отступ слева первой кнопки от края панели;
property ShowCaptions: Boolean; – определяет, требуется ли показывать заголовок панели;
67
3.31 TToolButton
Класс TToolButton является наследником TGraphicControl и служит для
создания кнопок на ToolBar.
Свойства класса TToolButton:
property Down: Boolean; – определяет, нажата ли кнопка;
property Grouped: Boolean; – определяет, является ли кнопка членом группы;
property Style: TToolButtonStyle; – определяет тип кнопки;
tbsButton – обычная кнопка;
tbsCheck – западающая кнопка (необходимо для группы);
tbsSeparator –кнопка-разделитель, не может быть нажата, может иметь
произвольную ширину;
property ImageIndex: TImageIndex; – определяет номер изображения в списке
изображений;
property Action: TBasicAction; – (наследуется из TControl) определяет, действие, связанное с кнопкой.
Все события наследуются от TControl.
3.32 TActionList
Класс TActionList является непрямым наследником TComponent и служит
для создания списка действий. Как правило, используются сами действия, поэтому свойства, методы и события данного класса не рассматриваем.
3.33 TAction
Класс TAction является непрямым наследником TComponent и служит
для создания отдельного действий.
Свойства класса TAction:
property Caption: string; – определяет описание действия, например строку в
меню;
property Checked: Boolean; – определяет, помечено ли данное действие,
например строка в меню;
property Enabled: Boolean; – определяет, разрешено ли данное действие;
property Hint: string; – подсказка для данного действия;
property ImageIndex: TImageIndex; – номер изображения в списке изображений;
property Visible: Boolean; – определяет, отображается ли данное действие;
property OnExecute: TNotifyEvent; – возникает при выборе данного действия,
например, строки меню.
Такие же свойства есть элементов меню и кнопок. Установление их
свойства Action в одно из действий автоматически меняет эти свойства. Изме-
68
нение параметров свойств у действия тут же отражается на параметрах связанных с ним элементов.