Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > Pascal: Общие вопросы > Чтение/запись символа в любой точке экрана


Автор: e-moe 21.06.04, 16:04
Как записать/считать символ в любой точке экрана?


Первый вопрос решается довольно просто средствами Паскаля:

Для начала нужно вызвать процедуру GotoXY(x,y: byte) из модуля CRT. Эта процедура перемещает курсор в указанную строку (x) и указанный столбец (у).

Нумерация начинается с левого верхнего угла монитора: самая верхняя строка, самый левый символ имеют координаты (1,1), второй символ первой строки - (1, 2). Т.е. ось Ox направлена из левого верхнего угла монитора параллельно земле в правый верхний угол, а ось Oy направлена от левого верхнего угла в левый нижний.

После этого можно вывести символ/строку начиная с позиции курсора процедурами Write/Writeln. Таким образом можно вывести любой символ/строку в любое место экрана.

Примечание: в стандартном текстовом режиме, в котором работает Turbo Pascal размер экрана таков: 25 строк, 80 столбцов. Причём, если попытаться что-то написать в 25 строку, то экран автоматически передвинется вверх на 1 строку. Это не следует забывать. Но если вам все-таки нужно что-то туда записать то можно сделать так: вывести на экран в 24-ю строку текст, который вы хотите увидеть на 25 строке, а после этого вызвать 2 процедуры:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        GoToXY(1, 24);
        InsLine;


Последняя процедура сдвигает часть экрана, находящуюся на строке с курсором и все что ниже на 1 строку вниз, т.е. вставляет пустую строку, в которой впоследствии можно писать. Таким образом, мы печатаем на 24-й строке экрана, а потом сдвигаем её вниз.

Второй вопрос решить средствами Паскаля не удастся т.к. в Паскале нет функций возвращающих символ, находящийся в положении курсора. Для этого придется воспользоваться ассемблером:

Для этой цели ассемблере есть 8-я функция 10h прерывания, которая возвращает символ и его атрибуты, находящийся в положении курсора в регистр ЦП AX. Ну не буду вдаваться в подробности, а сразу дам код моей функции:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    Function GetChar(x,y:byte):char;   { функция возвращающих символ,
                                         находящийся в положении курсора }
    Var  Reg : Registers;         { Эта переменная дает доступ к регистрам ЦП }
    Begin
      GoToXY(x,y);                    { уже известная вам процедура, переводящая курсор
                                        в положение x,y на экране }
      With Reg do
        Begin
          AH:=8;            { Номер функции }
          BH:=0;            { Номер страницы }
                { именно в эту страницу видеопамяти паскаль
                              записывает все данные процедурами Write/WriteLn }
        End;
      Intr($10,Reg);        { вызываем 10h прерывание ЦП }
                { после этого символ хранится в AL, а
                  его атрибуты в AH }
      GetChar:=chr(reg.AL); { присваиваем выходное значение функции }
                { т.е. получаем символ с экрана }
     
    { если вам понадобится узнать атрибуты символа, тогда вместо
        GetChar:=chr(reg.AL);
    напишите
        GetChar:=reg.AH;
    и поменяйте выходной тип функции на byte как показана ниже:
    Function GetCharAtrib(x,y:byte):byte;
    }
    end;



Вот собственно и все...

P.S. Существует ещё один способ записать/считать символ с экрана - это прямая работа с видеопамятью, но об этом в моей следующей статье...

Автор: Romtek 21.09.04, 18:14
А ещё
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    {выводит символ в заданном месте, заданного цвета и фона}
    procedure PutSymbol (x, y: word; symbol, col, bg:byte);
    begin
      Memw[SegB800 : word((y-1) * 160 + (x-1) shl 1)] := bg shl 12 + col shl 8 + symbol;
    end;

Автор: antxyz 07.12.04, 20:56
Объявляешь тип:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    type tscr=array[0..24,0..79,0..2]of byte;

И пременную этого типа:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    var scr:tscr absolute $B800:$0000;

absolute $B800:$0000 обозначает, что эта перемення будет размещена в памяти по адресу $B800:$0000(область видеопамяти)

Теперь если хочешь,напиример, вывести символ 'A' с координатами (5,5)(левый верхний угол экрана имеет координаты (0,0)) пишешь:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    scr[5,5,0]:=ord(a);

А если присвоить scr[5,5,1] знасение x, т.е.:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    scr[5,5,1]:=x

то в позицию 5,5 запишется байт атрибута x, где x это:
fbbbcccc
76543210
f-flash 1-мигает,0-не мигает
bbb-цвет фона
cccc-цвет букв
Например белый по черному не мигающий:
f=0
bbb=black(0)
cccc=white(15)
x=0*2^7+black*2^4+white
при записи в правый нижний угол экрана скролинг не происходит!

Добавлено
Ответ на второй вопрос:
чтобы считать символ с координатами (x,y) впеременную a пишешь:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    a:=scr[x,y,0];

чтобы считать его атрибут:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    b:=acr[x,y,1];

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)