15.4.2. Позиционирование курсора
15.4.2.1. Процедура GotoXY( X, Y : Byte ). С помощью этой процедуры можно устанавливать курсор в столбец X и строку Y текущего окна. При этом последующая операция вывода текста на дисплей разместит первый символ выводимой строки в позиции (X, Y).
GotoXY использует систему координат текущего текстового окна, т.е. координаты (1, 1) соответствуют левому верхнему углу окна.
- 332 -
Если аргументы процедуры 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. На этом рисунке приведен еще
- 333 -
один пример, основанный на применении процедуры 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
- 334 -
| 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 могут эффективно использоваться в программах, работающих с пользователем в режиме полноэкранного диалога (редактора текстов, таблиц и т.п.).