|
Приложениe Г
Пример использования ООП
{* * * * Модуль с объектами экранного редактора * * * *}
unit Edit;
{* * * Интерфейс модуля * * *}
interface
const Len = 80; {размер элемента строки}
BackS = 8; {код клавиши Backspace}
Ent = 13; {код клавиши Enter}
Esc = 27; {код клавиши Esc}
type
tEkran = array[1..25, 1..80, 1..2] of Char;
{тип-массив видеопамяти}
tStringLen = string[Len]; {тип-элемент строки}
var
S: tEkran absolute $B800:$0000;
{видеопамять текстового режима}
Ch: Char; {вводимый символ}
{* * Объект связи в структуре * *}
type
pConnection = ^tConnection;
tConnection = object {предок последующих объектов}
PredElem: Pointer; {указатель на предыдущий элемент структуры}
NextElem: Pointer; {указатель на следующий элемент структуры}
procedure PutPredElem(PredEl: Pointer);
{задание указателя на предыдущий элемент}
procedure PutNextElem(NextEl: Pointer);
{задание указателя на следующий элемент}
function GetPredElem: Pointer;
{получение указателя на предыдущий элемент}
function GetNextElem: Pointer;
{получение указателя на следующий элемент}
end;
{* * Объект - структура * *}
type
pStrucrure = ^tStructure;
tStructure = object(tConnection) {потомок типа tConnection}
FirstElem: Pointer; {указатель на первый элемент}
LastElem: Pointer; {указатель на последний элемент}
constructor Init; {фиктивная подпрограмма}
procedure PutFirstElem(FirstEl: Pointer);
{задание указателя на первый элемент}
procedure PutLastElem(LastEl: Pointer);
{задание указателя на последний элемент}
function GetFirstElem: Pointer;
{получение указателя на первый элемент}
function GetLastElem: Pointer;
{получение указателя на последний элемент}
function InitElem: Pointer; virtual;
{инициализация элемента}
procedure DispElem(PointDel: Pointer); virtual;
{удаление элемента из динамической памяти}
procedure PutConnection(FirstPoint, SecondPoint:Pointer);
{установление связи между элементами}
procedure NewEKPointPredEl, PointNextEl: Pointer);
{включение нового элемента}
procedure DelEKPointDel: Pointer);
{удаление элемента}
end;
{* * Объект - элемент строки * *}
pElLine = ^tElLine;
tElLine = object(tConnection) {потомок типа tConnection}
Info: tStringLen; {строка текста}
constructor Init; {конструктор объекта}
procedure PutSymb(Ch: Char; NomlnEl: Byte; var OldSym: Char);
{размещение символа Ch в элементе строки в позиции NomlnEl; в OldSym - последний удаленный из строки символ}
function GetSymb(NomInEl: Byte): Char;
{получение символа из позиции NomlnEl}
procedure PutString(Str: tStringLen; BegNom: Byte);
{размещение строки Str, начиная с позиции BegNom}
function GetString(BegNom: Byte): tStringLen;
{получение части строки, начиная с позиции BegNom}
end;
{* * Объект - строка * *}
pLine = ^tLine;
tLine = object(tStructure) {потомок типа tStructure}
constructor Init; {конструктор объекта}
destructor Done; {деструктор объекта}
function InitElem: Pointer; virtual;
{инициализация элемента}
procedure DispElem(PointDel: Pointer); virtual;
{удаление элемента из динамической памяти}
procedure GetPointElLineAndNomlnEKNom: Word; var PointElLine: PElLine; var NomlnEl: Byte; NewLine: Boolean);
{Получение указателя PointElLine на элемент строки, в котором находится символ с абсолютным номером Nom,
и номер позиции этого символа NomlnEl в элементе строки; если NewLine = True, при отсутствии требуемого элемента строки он создается}
procedure PutSymb(Nom: Word);
{размещение символа Ch в строке с абсолютным номером Nom позиции в строке}
function GetSymb(Nom: Word): Char;
{получение символа с абсолютным номером Nom позиции в строке}
procedure LastNotBlank(var PointElLine: PElLine; var NomAbs: Word; var NomlnEl: Byte);
{получение указателя PointElLine на элемент строки, в котором находится последний символ, не являющийся пробелом,
абсолютного номера NomAbs этого символа в строке и номера позици этого символа NomlnEl в элементе строки}
end;
{* * Объект - текст * *}
type
pText = ^tText;
tText = object(tStructure) {потомок типа tStructure}
Xabs,Yabs: Word;
{абсолютные координаты текущего символа в тексте}
SmX,SmY: Word;
{координаты начала экрана в тексте (отсчет от нуля)}
CurrentPointLine: pLine;
{указатель на текущую строку текста (соответствует Yabs)}
OnlyLine,FullEkran: Boolean;
{признак необходимости вывода на экран текущей строки или всего текста}
constructor Init; {конструктор объекта}
destructor Done; {деструктор объекта}
function InitElem: Pointer; virtual;
{инициализация строки}
procedure DispElem(PointDel: Pointer); virtual;
{удаление строки из динамической памяти}
procedure PutX(X: Word);
{задание координат X - абсолютной и смещения начала экрана, если Х=0, координата не меняется}
procedure PutY(Y: Word);
{задание координат Y - абсолютной и смещения начала экрана, если Y=0 или больше максимального числа, координата не меняется}
procedure IncX; {увеличение координат X на 1}
procedure DecX;
{уменьшение координат X на 1, если Xabs=0, координата не меняется}
procedure IncY;
{увеличение координат Y на 1 и получение следующего текущего указателя на строку, если след. строки нет, координата не меняется}
procedure DecY;
{уменьшение координат Y на 1 и получение предыдущего текущего указателя на строку, если Yabs=0, координата не меняется}
function GetX: Word; {получение координаты Xabs}
function GetY: Word; {получение координаты Yabs}
function GetPointLine(Y: Word): pLine;
{получение указателя на строку с координатой Y}
procedure PutSymb;
{помещение символа в текст с текущими координатами}
function GetSymb: Char;
{получение символа с текущими координатами}
procedure PutEkran; {вывод текста на экран}
PutCursor; {вывод курсора на экран}
end;
{* * Объект - выполнение операции * *}
type
pOperation = ^tOperation;
tOperation = object {предок последующих объектов}
constructor Init;
procedure PutNewSymb; {обработка введенного символа}
procedure Ins; virtual; {размещение символа в тексте}
end;
{* * Объект - Размещение символа с кодом больше 30 * *}
pInsertSymbol = ^tInsertSymbol;
tInsertSymbol = object(tOperation)
{потомок типа tOperation}
Symb: Char; {размещаемый символ}
Constructor Init; {конструктор объекта}
Procedure Ins; virtual; {размещение символа}
end;
{* * Объекты - перемещение курсора на одну позицию **}
pInsertUp = ^tInsertUp;
tInsertUp = object(tOperation)
constructor Init; {конструктор объекта}
procedure Ins; virtual; {перемещение курсора вверх}
end;
pInsertDn = ^tInsertDn;
tInsertDn = object(tOperation)
constructor Init; {конструктор объекта}
procedure Ins; virtual; {перемещение курсора вниз}
end;
pInsertLeft = ^tInsertLeft;
tInsertLeft = object(tOperation)
constructor Init; {конструктор объекта}
procedure Ins; virtual; {перемещение курсора влево}
end;
pInsertRight = ^tInsertRight;
tInsertRight = object(tOperation)
constructor Init; {конструктор объекта}
procedure Ins; virtual; {перемещение курсора вправо}
end;
{* * Объект - обработка клавиши Enter * *}
pInsertEnter = ^tInsertEnter;
tInsertEnter = object(tOperation)
constructor Init; {конструктор объекта}
procedure Ins; virtual; {формирование новой строки}
end;
{** Объект -обработка клавиши Backspace **}
pInsertBackSpace = ^tInsertBackSpace;
tInsertBackSpace = object(tOperation)
constructor Init; {конструктор объекта}
procedure Ins; virtual; {удаление символа или объединение двух строк}
end;
var
PointText: pText; {указатель создаваемого текста}
Symbol: pInsertSymbol; {указатель на объект - размещение символа}
Up: pInsertUp; {указатель на объект - курсор вверх}
Dn: pInsertDn; {указатель на объект - курсор вниз}
Left: pInsertLeft; {указатель на объект - курсор влево}
Right: pInsertRignt; {указатель на объект - курсор вправо}
Enter: pInsertEnter; {указатель на объект - обработка клавиши Enter}
Backspace: pInsertBackSpace; {указатель на объект - обработка клавиши Backspace}
StringOfBlanks: tStringLen; {строка пробелов}
{* * * Исполнительная часть модуля * * *}
implementation
uses Crt;
{* * Подпрограммы tConnection * *}
procedure tConnection.PutPredElem(PredEl: Pointer);
begin
PredElem := PredEl
end;
procedure tConnection.PutNextElem(NextEl: Pointer);
begin
NextElem := NextEl
end;
function tConnection.GetPredElem: Pointer;
begin
GetPredElem := PredElem
end;
function tConnection.GetNextElem: Pointer;
begin
GetNextElem := NextElem
end;
{* * Подпрограммы tStructure * *}
constructor tStructure.Init;
begin {фиктивная подпрограмма}
end;
procedure tStructure.PutFirstElem(FirstEl: Pointer);
begin
FirstElem := FirstEl
end;
procedure tStructure.PutLastElem(LastEl: Pointer);
begin
LastElem := LastEl
end;
function tStructure.GetFirstElem: Pointer;
begin
GetFirstElem := FirstElem
end;
function tStructure.GetLastElem: Pointer;
begin
GetLastElem := LastElem
end;
function tStructure.InitElem: Pointer;
begin {фиктивная подпрограмма}
end;
procedure tStructure.DispElem(PointDel: Pointer);
begin {фиктивная подпрограмма}
end;
procedure tStructure.PutConnection(FirstPoint, SecondPoint:Pointer);
begin
if FirstPointonil then {первый элемент существует - связь со вторым}
pLine(FirstPoint)^.PutNextElem(SecondPoint)
else {нет - второй элемент - начальный}
PutFirstElem(SecondPoint);
if SecondPoint <>nil then {второй элемент существует - связь с первым}
pLine(SecondPoint)^.PutPredElem(FirstPoint)
else {нет - первый элемент - конечный}
PutLastElem(FirstPoint);
end ;
procedure tStructure.NewEl(PointPredEl, PointNextEl: Pointer);
var NewPoint: Pointer;
begin
NewPoint := InitElem; {новый элемент}
PutConnection(PointPredEl, NewPoint);
{связь с предыдущим элементом}
PutConnection(NewPoint, PointNextEl);
{связь со следующим элементом}
end;
procedure tStructure.DelEl(PointDel: Pointer);
var Point: pLine;
begin
Point := PointDel;
PutConnection(Point^.GetPredElem, Point^.GetNextElem);
{установление связей минуя удаляемый элемент}
DispElem(PointDel) {удаление элемента}
end;
{** Подпрограммы tElLine **)
constructor tElLine.Init;
begin
Info := StringOfBlanks; {заполнение строки пробелами}
end;
procedure tElLine.PutSymb(Ch: Char; NomInEl: Byte; var OldSym: Char);
begin
if (NomInEl > 0) and (NomInEl <= Len) then
{допустимый номер символа}
begin
OldSym := Info[Len]; {сохранение последнего символа}
Insert(Ch, Info, NomInEl) {размещение символа}
end
end;
function tElLine.GetSymb(NomInEl: Byte): Char;
begin
if (NomInEl > 0) and (NomInEl <= Len) then
{допустимый номер символа}
GetSymb := Info[NomInEl]
else {нет - помещение пробела}
GetSymb := ' '
end;
procedure tElLine.PutString(Str: tStringLen; BegNom: Byte);
begin
Insert(Str, Info, BegNom) {размещение строки}
end;
function tElLine:GetString(BegNom: Byte): tStringLen;
begin
GetString := Copy(Info.BegNom,Len) {получение части строки}
end;
{* * Подпрограммы tLine * *}
constructor tLine.Init;
begin
NewEl(nil, nil) {задание связей первого элемента}
end;
destructor tLine.Done;
var P1 ,P2: pElLine;
begin
P1 : = GetFirstElem; {указатель на первый элемент}
While P1 <> nil do {пока есть очередной элемент . . .}
begin
Р2 := P1^.GetNextElem; {указатель на следующий элемент}
Dispose(P1); {удаление элемента строки}
Р1 := Р2
end
end;
function tLine.InitElem;
begin
InitElem : = New(pElLine, Init); {создание нового элемента строки}
end;
procedure tLine.DispElem(PointDel: Pointer);
begin
Dispose(pElLine(PointDel)); {удаление элемента строки}
end;
procedure tLine.GetPointElLineAndNomInEl(Norn: Word;
var PointElLine: PElLine;
var NomInEl: Byte; NewLine: Boolean);
begin
PointElLine := GetFirstElem; {первый элемент строки}
while (Nom > Len) do {если номер символа больше размера строки...}
begin
if NewLine and (PointElLine^.GetNextElem=nil) then
{если нет следующего элемента, а его следует создать...}
NewEl(PointElLine, nil);
{создание нового элемента}
if PointElLine <> nil then
{если нет следующего элемента...}
PointElLine := PointElLine^.GetNextElem;
{указатель на следующий элемент}
Nom := Nom-Len
{уменьшение порядкового номера символа на размер элемента строки}
end;
if NewLine and (PointElLine = nil) then
{если нет следующего элемента, а его следует создать...}
NewEl(GetLastElem, nil); {создание нового элемента}
if PointElLine <> nil then {если есть элемент строки...}
NomInEl := Nom {получение номера}
else
NomInEl := 0 {иначе номер равен нулю}
end;
procedure tLine.PutSymb(Nom: Word);
var PointElLine: pElLine;
OldSym: Char;
NomInEl: Byte;
NewPointElLine: pElLine;
begin
GetPointElLineAndNomInEl(Nom, PointElLine, NomInEl, True);
{получение указателя на элемент строки и номера позиции символа}
PointElLine^.PutSymb(Ch, NomInEl, OldSym);
{размещение символа в элементе строки}
while (OldSym <> ' ') or (PointElLine^.GetNextElem <> nil)
do
{пока последний символ не пробел или есть следующий элемент строки...}
begin
if PointElLine^.GetNextElem = nil then
{если нет следующего элемента строки...}
NewEl(PointElLine, nil);
{создать его}
PointElLine := PointElLine^.GetNextElem;
{следующий элемент}
PointElLine^.PutSymb(OldSym, 1, OldSym)
{последний символ - в первую позицию}
end
end;
function tLine.GetSymb(Nom: Word): Char;
var PointElLine: pElLine;
NomInEl: Byte;
begin
GetPointElLineAndNomInEl(Nom, PointElLine, NomInEl, False);
{получение указателя на элемент строки и номера позиции символа}
if PointElLine <> nil then {если есть символ...}
GetSymb := PointElLine^.GetSymb(NomInEl)
else
GetSymb := ' ' {иначе - пробел}
end;
procedure tLine.LastNotBlank(var PointElLine: PElLine;
var NomAbs: Word; var NomInEl: Byte);
var Point: pElLine;
TekNom: Word;
i: Byte;
begin
Point := GetFirstElem; {указатель на первый элемент строки}
NomAbs := 0;
TekNom := 0;
repeat
for i := 1 to Len do
begin
Inc(TekNom);
if Point^.GetSymb(i) <> ' ' then
NomAbs : = TekNom {очередной символ - не пробел}
end;
Point : = Point^.GetNextElem
until Point = nil; {пока есть очередной элемент}
GetPointElLineAndNomInEl(NomAbs, PointElLine, NomInEl, False);
end;
{* * Подпрограммы tText * *}
constructor tText.Init;
begin
NewEl(nil, nil); {задание связей первой строки}
Xabs := 1; {абсолютные координаты}
Yabs := 1; {курсора}
SmX := 0; {смещение начала экрана}
SmY := 0;
CurrentPointLine:=GetFirstElem; {текущий указатель}
OnlyLine := False; {признаки вывода на экран}
FullEkran := False;
New(Symbol, Init); {объект - размещение символа}
New(Up, Init); {объект - курсор вверх}
New(Dn, Init); {объект - курсор вниз}
New(Left, Init); {объект - курсор влево}
New(Right, Init); {объект - курсор вправо}
New(Enter, Init); {объект - обработка Enter}
New(BackSpace, Init); {объект - обработка Backspace}
end;
destructor tText.Done;
var P1, P2: pLine;
begin
P1 := GetFirstElem; {указатель на первую строку}
while P1 <> nil do
begin
P2 : = P1^.GetNextElem; {следующая строка}
Dispose(P1, Done); {удаление строки}
P1 := P2
end;
Dispose(Symbol); {удаление объекта - размещение символа}
Dispose(Up); {удаление объекта - курсор вверх}
Dispose(Dn); {удаление объекта - курсор вниз}
Dispose(Left); {удаление объекта - курсор влево}
Dispose(Right); {удаление объекта - курсор вправо}
Dispose(Enter); {удаление объекта - обработка Enter}
Dispose(BackSpace); {удаление объекта - обработка Backspace}
end;
function tText.InitElem: Pointer;
begin
InitElem := New(pLine,Init)
end;
procedure tText.DispElem(PointDel: Pointer);
begin
Dispose(pLine(PointDel) ,Done)
end;
procedure tText.PutX(X: Word);
begin
if X <> 0 then
begin
Xabs := X;
if SmX >= Xabs then
begin
SmX := Xabs - 1;
FullEkran := True
end
else if SmX + 80 < Xabs then
begin
SmX := Xabs - 80;
FullEkran := True
end
end
end;
procedure tText.PutY(Y: Word);
var P: pLine;
begin
if Y <> 0 then
begin
P : = GetPointLine(Y);
if P <> nil then
begin
Yabs := Y;
if SmY > = Yabs then
begin
SmY := Yabs - 1;
FullEkran := True
end
else if SmY + 25 < Yabs then
begin
SmY := Yabs - 25;
FullEkran : = True
end;
CurrentPointLine := P
end
end
end;
procedure tText.IncX;
begin
Inc(Xabs);
if SmX + 80 < Xabs then
begin
SmX := Xabs - 80;
FullEkran := True
end
end;
procedure tText.DecX;
begin
if Xabs > 1 then
begin
Dec(Xabs);
if SmX >= Xabs then
begin
SmX : = Xabs - 1;
FullEkran := True
end
end
end;
procedure tText.IncY;
begin
if CurrentPointLine^ .NextElem <> nil then
begin
Inc(Yabs);
if SmY + 25 < Yabs then
begin
SmY := Yabs - 25;
FullEkran := True
end;
CurrentPointLine := CurrentPointLine^.NextElem
end
end;
procedure tText.DecY;
begin
if Yabs > 1 then
begin
Dec(Yabs);
if SmY >= Yabs then
begin
SmY := Yabs - 1;
FullEkran := True
end;
CurrentPointLine : = CurrentPointLine^.PredElem
end
end;
function tText.GetX: Word;
begin
GetX := Xabs
end;
function tText.GetY: Word;
begin
GetY := Yabs
end;
function tText.GetPointLine(Y: Word): pLine;
var PointLine: pLine;
i: Word;
begin
PointLine : = GetFirstElem; {указатель на первую строку}
for i := 2 to Y do
if PointLine <> nil then {если есть текущая строка...}
PointLine := PointLine^.GetNextElem;
{взять следующую строку}
GetPointLine : = PointLine
end;
procedure tText.PutSymb;
begin
CurrentPointLine^.PutSymb(Xabs)
end;
function tText.GetSymb: Char;
begin
GetSymb : = CurrentPointLine^.GetSymb(Xabs)
end;
procedure tText.PutEkran;
var PointLine: pLine;
i, j: Byte;
XRez, YRez: Word;
XSmRez, YSmRez: Word;
begin
XRez : = Xabs; YRez := Yabs;
XSmRez := SmX; YSmRez := SmY;
if FullEkran then {если выводить весь экран...}
begin
PutY(SmY +1);
for i := 1 to 25 do
begin
PutX(SmX + 1);
if CurrentPointLine <> nil then
{есть очередная строка}
begin
for j := 1 to 80 do
begin
S[i, j, 1] := GetSymb;
IncX
end;
CurrentPointLine := CurrentPointLine^.NextElem
end
else {нет строки - поместить пробелы}
for j := 1 to 80 do
begin
S[i, j, 1] := ' ';
IncX
end;
SmX : = XSmRez;
end;
FullEkran : = False; {сбросить признак вывода}
SmY := YSmRez;
PutX(XRez);
PutY(YRez)
end
else if OnlyLine then {если выводить одну строку}
begin
PutX(SmX + 1) ;
for j := 1 to 80 do
begin
S[Yabs - SmY, j, 1] := GetSymb;
IncX
end;
OnlyLine := False;
SmX := XSmRez;
PutX(XRez)
end
end;
procedure tText.PutCursor;
begin
GotoXY(Xabs - SmX, Yabs - SmY);
end;
{* * Подпрограммы tOperatin * *}
constructor tOperation.Init;
begin {фиктивная подпрограмма}
end;
procedure tOperation.Ins;
begin
end;
procedure tOperation.PutNewSymb;
begin
Ins;
with PointText^ do
begin
PutEkran;
PutCursor
end
end;
{** Подпрограммы tInsertSymbol **}
constructor tInsertSymbol.Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertSymbol.Ins;
var PointLine: pLine;
begin
with PointText^ do
begin
PutSymb; {размещение символа}
IncX; {сдвиг курсора вправо}
if not FullEkran then {если выводится не весь экран...}
OnlyLine : = True {выводится одна строка}
end
end ;
{* * Подпрограммы перемещения курсора * *}
constructor tlnsertUp.Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertUp.Ins;
begin
with PointText^ do
DecY
end;
constructor tInsertDn.Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertDn.Ins;
begin
with PointText^ do
IncY
end;
constructor tInsertLeft.Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertLeft.Ins;
begin
with PointText^ do
DecX
end;
constructor tInsertRight. Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertRight.Ins;
begin
with PointText^ do
IncX
end;
{** Подпрограммы tlnsertEnter **}
constructor tInsertEnter.Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertEnter.Ins;
var PointElLine: pElLine;
NomAbs: Word;
NomlnEl: Byte;
NewPoint: pLine;
Point: pElLine;
PointOldElLine: pelLine;
begin
with PointText^ do
begin
CurrentPointLine^.LastNotBlank(PointElLine, NomAbs, NomInEl);
{координаты последнего символа строки, не являющегося пробелом}
CurrentPointLine^.GetPointElLineAndNomInEl(GetX, PointElLine, NomInEl, False);
{внутренние координаты курсора}
if GetX = 1 then {если начало строки...}
begin
NewEl(CurrentPointLine^.GetPredElem, CurrentPointLine);
{новая строка перед текущей}
CurrentPointLine := CurrentPointLine^.GetPredElem
end
else {иначе...}
begin
NewEl(CurrentPointLine, CurrentPointLine^.GetNextElem);
{новая строка после текущей}
if (NomInEl <> 0) and (GetX < = NomAbs) then
{если символ существует и не является заключительным пробелом...}
begin
NewPoint := CurrentPointLine^.GetNextElem;
{следующая строка}
NewPoint^ . PutLastElem(CurrentPointLine^ . GetLastElem);
{указатель на последний элемент -из предыдущей строки}
if NomInEl = 1 then
{если начало элемента строки...}
begin
Dispose(NewPoint^.FirstElem);
{удаление строки из нового объекта}
CurrentPointLine^.PutConnection(PointElLine^.GetPredElem, nil);
NewPoint^.PutConnection(nil, PointElLine)
{помещение остатка предыдущей строки в следующую строку}
end
else {иначе...}
begin
Point : = NewPoint^.GetFirstElem;
{первый элемент новой строки}
PointOldElLine := PointElLine^.GetNextElem;
{удаляемая часть текущей строки}
CurrentPointLine^.PutConnection( PointElLine, nil);
{оформление конца текущей строки}
NewPoint^.PutConnection(Point, PointOldElLine);
{добавление остатка текущей строки к новой строке}
Point^.PutString(PointElLine^.GetString(NomInEl), 1);
{добавление конца последнего элемента в конец первого новой строки}
PointElLine^.PutString(StringOfBlanks, NomInEl);
{пробелы в конец последнего элемента};
while Point^.GetNextElem <> nil do
{пока есть следующий элемент...}
begin
PointOldElLine := Point^.GetNextElem;
{следующий элемент}
Point^.PutString(PointOldElLine^.GetString(l), Len - NomlnEl + 2);
{начало следующего элемента - в конец предыдущего}
Point : = PointOldElLine;
{следующий элемент}
Point^.PutString( Point^.GetString(NomInEl), 1);
{конец элемента - в начало}
end;
Point^.PutString(StringOfBlanks, Len - NomInEl + 2) ;
{пробелы в конец последнего элемента}
end
end
end;
PutX(1);
IncY; {новые координаты}
FullEkran : = True {обновить весь экран}
end
end;
{* * Подпрограммы tInsertBackSpace * *}
constructor tInsertBackSpace.Init;
begin {фиктивная подпрограмма}
end;
procedure tInsertBackSpace.Ins;
var PointElLine: pElLine;
PointNextElLine: pElLine;
NomInEl: Byte;
NewPoint,OldPoint: pLine;
NomAbs: Word;
Point,Point1: pElLine;
Ch: Char;
begin
with PointText^ do
if (GetX <> 1) or (GetY <> 1) then
{если не начало текста...}
begin
CurrentPointLine^ .GetPointElLineAndNomInEl(GetX, PointElLine, NomInEl, False);
{внутренние координаты курсора}
if NomInEl = 0 then {если нет символа...}
DecX {сдвиг курсора влево}
else
if GetX <> 1 then {если не начало строки...}
begin
if NomInEl =1 then
{если начало элемента...}
begin
PointElLine : = PointElLine^.GetPredElem;
{указатель на предыдущий элемент}
NomInEl := Len + 1
{корректировка номера элемента в строке}
end;
PointElLine^.PutString(PointElLine^. GetString(NomlnEl), NomlnEl - 1);
{удаление текущего символа}
PointNextElLine := PointElLine^.GetNextElem; {следующий элемент строки}
while PointNextElLine <> nil do
{пока есть следующий элемент...}
begin
PointElLine^.PutSymb(PointNextElLine^. GetSymb(l), Len, Ch);
{первый символ следующего элемента - в конец предыдущего}
PointElLine := PointNextElLine;
{следующий элемент строки}
PointNextElLine := PointNextElLine^.GetNextElem;
{следующий элемент строки}
PointElLine^.PutString(PointElLine^. GetString(2), 1);
{сдвиг новой строки на символ влево}
end;
PointElLine^.PutSymb(' ', Len, Ch);
{пробел в последнюю позицию последнего элемента}
DecX; {задание новых координат}
if not FullEkran then
{если не выводить весь экран...}
OnlyLine := True
{то выводить текущую строку}
end
else {начало строки - объединение строк}
begin
NewPoint := CurrentPointLine^.GetPredElem;
{предыдущая строка}
OldPoint := CurrentPointLine^.GetNextElem;
{последующая строка}
PointNextElLine:= PointElLine;
{последующий элемент строки}
NewPoint^.LastNotBlankCPointElLine, NomAbs, NomInEl);
{последний символ предыдущей строки, не являющийся пробелом}
NewPoint^.PutLastElem(CurrentPointLine^. GetLastElem);
{конец предыдущей строки - конец текущей строки}
PutConnection(NewPoint, OldPoint);
{связь предыдущей строки с последующей минуя текущую}
Point := PointElLine^.GetNextElem;
{следующий элемент текущей строки}
while Point <> nil do {пока есть следующий элемент...}
begin
Point1 := Point^.GetNextElem;
{следующий элемент}
Dispose(Point);
{удаление элемента}
Point := Point1
{следующий элемент}
end;
PutConnection(PointElLine, PointNextElLine);
{связь элементов предыдущей строки с элементами текущей}
Dispose(CurrentPointLine);
{удаление текущей строки}
if NomInEl <> Len then
{если присоединение не к концу предыдущего элемента...}
while PointElLine^.GetNextElem <> nil do {пока есть следующий элемент...}
begin
PointNextElLine := PointElLine^.GetNextElem; PointElLine^.PutString(PointNextElLine^.GetStringC1),NomlnEl + 1);
{начало следующего элемента - в конец текущего элемента}
PointNextElLine^.PutString(PointNextElLine^.GetString(Len - NomInEl + 1), 1);
{конец следующей строки - в ее начало}
PointElLine := PointNextElLine
{следующий элемент }
end;
PointElLine^.PutString(StringOfBlanks,NomlnEl + 1);
{пробелы в конец последнего элемента}
PutX(NomAbs +1);
PutY(GetY - 1);
FullEkran := True
end
end
end;
{* * Секция инициализации * *}
var i: Byte;
begin
for i := 1 to Len do
StringOfBlanks[i] := ' ';
StringOfBlanks[0] := Chr(Len);
New(PointText, Init); {создание объекта}
end.
{* * * * Файл с основной программой * * * *}
uses Crt,Edit;
begin
TextBackGround(Blue); {цвет фона}
TextColor(White); {цвет символов}
ClrScr; {очистка экрана}
GotoXY(l,l); {курсор в начало координат}
repeat
Ch := ReadKey; {чтение символа}
if Ch = Chr(0) then {сложный код клавиши}
begin
Ch := ReadKey; {вторая половина кода}
case Ord(Ch) of
72: Up^.PutNewSymb; {клавиша Up}
80: Dn^.PutNewSymb; {клавиша Dn}
75: Left^.PutNewSymb; {клавиша Left}
77: Right^.PutNewSymb {клавиша Right}
end
end
else if Ch > Chr(31) then
Symbol^.PutNewSymb {размещение символа}
else if Ch = Chr(Ent) then
Enter^.PutNewSymb {клавиша Enter}
else if Ch = Chr(BackS) then
Backspace^.PutNewSymb {клавиша Backspace}
until Ch = Chr(Esc); {пока не нажата клавиша Esc}
Dispose(PointText, Done); {удаление объекта}
TextBackGround(DarkGray); {цвет фона}
TextColor(LightGray); {цвет символов}
ClrScr {очистка экрана}
end.
|
|
|