15.4.2.1. Процедура GotoXY( X, Y : Byte ). С помощью этой процедуры можно устанавливать курсор в столбец X и строку Y текущего окна. При этом последующая операция вывода текста на дисплей разместит первый символ выводимой строки в позиции (X, Y).
GotoXY использует систему координат текущего текстового окна, т.е. координаты (1, 1) соответствуют левому верхнему углу окна. {331}
Если аргументы процедуры X и Y окажутся вне текущего окна, то ее вызов не будет иметь никакого эффекта. Нижние разрешенные значения для X и Y всегда равны 1, а верхние определяются размерами текущего окна. С помощью процедуры GotoXY можно выводить строки на экран вертикально. Пример этого приведен на рис. 15.9.
USES CRT; { подключен CRT }
PROCEDURE VertStr( X,Y : Byte; S : String );
VAR
Len : Byte absolute S; { длина строки S } i : Byte; { параметр цикла }
BEGIN
for i:=1 to Len do begin
GotoXY( X, Y+Pred(i) ); { назначение позиции вывода }
Write( S[i] ) { вывод очередного символа }
end {for}
END;
BEGIN
ClrScr; { очистка экрана }
VertStr( 5,5, 'Вертикально!' ); { вывод строки } ReadLn { пауза }
END.
Рис. 15.9
При выводе символов или другой информации по мере необходимости на экране происходит прокрутка, или сдвиг, изображения. Это всегда имеет место при выводе кодов конца строки (LF, код 10) в последней строке окна операторами WriteLn и ReadLn или когда выводимая строка не умещается в той же последней строке текстового окна. А, например, вывод типа
GotoXY( 5, 25 ); Write( 'строка' );
не вызовет сдвига вверх, потому что оператор Write не переводит строки. Однако вывод хотя бы одного символа в правый нижний угол текстового окна вызовет прокрутку:
GotoXY( 80,25 ); Write( '*' );
и символ '*' окажется уже в 24-й строке, а не в 25-й.
Эту неприятную особенность всегда приходится учитывать при построении программ, работающих со всем полем экрана. Как это делать, можно увидеть из рис. 15.10. На этом рисунке приведен еще {332} один пример, основанный на применении процедуры GotoXY. В нем вводится процедура, которая закрашивает прямоугольную область на экране любым символом в текущем цветовом атрибуте, причем заполнение области происходит по спирали.
USES CRT;
{ Процедура закраски квадратной области экрана }
{ с диагональю (X0,Y0)-(X,Y) символом Ch }
{ ms - период задержки при закраске }
PROCEDURE Spiral( Xo,Yo,X,Y: Byte; ms: Word; Ch: Char );
VAR
height, width, j : Byte;
с : Integer;
BEGIN
с := 1; { начальное значение с }
width := X - Х0 + 1; { начальная ширина поля }
height := Y - Y0 + 1; { начальная высота поля }
repeat { основной цикл }
for j:=1 to width do begin { вправо/влево }
GotoXY( X,Y ); Write( Ch ); { ставим символ }
if (Y>Hi(WindMax)) and (X>Lo(WindMax))
then begin { !!! Обработка }
GotoXY( 1,1 ); InsLine { особого случая
end;
Delay( ms ); { задержка }
X := X – с
end; {for j}
X := X + с; { восстановление Х после цикла }
Dec( height); { поле закраски стало ниже }
for j:=1 to height do begin { вверх/вниз }
Y := Y - c;
GotoXY( X,Y ); Write( Ch ); Delay( ms )
end; {for j}
Dec( width); { Поле закраски стало уже }
X := X + с; {и стартовое X сдвинулось. }
с := -1*с { смена направления }
until (height<1) or (width<1); { условие окончания }
GotoXY( 1, 1 ) { курсор в начало }
END;
VAR i : Byte; { --ПРИМЕР ИСПОЛЬЗОВАНИЯ--}
BEGIN
ClrScr;
Spiral( 1,1,80,25, 2, #176 );
Рис. 15.10 {333}
for i:=1 to 10 do begin
TextAttr := i;
Spiral( 2*i, i, 5*i, 2*i, 4, Chr( 47+i ) )
end; {for}
ReadLn { пауза до нажатия клавиши ввода }
END.
Рис. 15.10 (окончание)
Комментарий к особому случаю. При попытке записи в правый нижний угол окна символа происходит сдвиг (прокрутка) изображения вверх. Во избежание этого закраска начинается с наибольших значений X и Y, и если они совпадают с углом окна, то сразу же проводится сдвиг изображения назад, вниз.
15.4.2.2. Функции WhereX и WhereY. Эти функции нужны для программного опроса текущего местоположения курсора в текстовом окне. Они возвращают значения координат курсора в текущем окне. Можно считать, что пара функций WhereX и WhereY обратна процедуре GotoXY.
Правила нахождения столбца (WhereX) и строки (WhereY) курсора несложны. Их всего четыре:
1) сразу после команды GotoXY (X, Y) функции возвращают значения X и Y соответственно;
2) после оператора Write курсор стоит сразу за последним символом выводимой строки (если не выводятся специальные символы типа #8, #10 или #13);
3) после операторов Read, ReadLn, WriteLn курсор стоит в первом столбце строкой ниже;
4) после команд, относящихся ко всему окну (экрану), таких как ClrScr, TextMode, Window, курсор имеет координаты (1,1).
Функции WhereX и WhereY могут эффективно использоваться в программах, работающих с пользователем в режиме полноэкранного диалога (редактора текстов, таблиц и т.п.).