Справочник от Автор24
Поделись лекцией за скидку на Автор24

Pascal. ООП. Delphi

  • 👀 376 просмотров
  • 📌 303 загрузки
Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Pascal. ООП. Delphi» pdf
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'; символ подчеркивания '_';  разделители (пробел, символы в диапазоне 031, комментарии);  специальные символы + – * / = , ' . : ; < > [ ] ( ) { } ^ @ $ #;  символы, используемые только в строках символов и комментариях (%, русские буквы). Идентификатор – имя любого элемента программы. Начинается с буквы или '_'. (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 -91018.. 91018 Cardinal 0..2147483647 Идентификатору с большим диапазоном значение может быть присвоен идентификатор с меньшим диапазоном значений, но не наоборот. Существует несколько логических типов, однако наиболее распространенным является тип Boolean, принимающий значения True либо False (0) (4<>5). Символьный тип применяется для описания множества значений символов ПК (Char). Каждому символу присвоен код в диапазоне от 0255. Символы с кодом 031 являются служебными ('a'). Вещественные типы, строго говоря, тоже имеют конечное множество значений, однако число таких значений настолько велико, что сопоставить с каждым порядковый номер не представляется возможным. Название Диапазон Real 5.010-324.. 1.710308 Single 1.510-45.. 3.41038 Double 5.010-324.. 1.710308 Extended 3.410-4951.. 1.1104932 Строковые типы служат, в отличии от символьного, для хранения групп взаимосвязанных символов. Основным строковым типом является 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 нение параметров свойств у действия тут же отражается на параметрах связанных с ним элементов.
«Pascal. ООП. Delphi» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Найди решение своей задачи среди 1 000 000 ответов
Найти

Тебе могут подойти лекции

Смотреть все 588 лекций
Все самое важное и интересное в Telegram

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

Перейти в Telegram Bot