На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила ЧаВо (FAQ) разделов Паскаля
В этом разделе разрешено создавать только темы, в которых описано РЕШЕНИЕ какой-либо общей проблемы, или описание какого-либо аспекта языка Паскаль.
Обсуждение уже созданных тем разрешено, но только конструктивное, например указание на ошибку или уточнение имеющегося текста.

Также читать Требования к оформлению статей
Модераторы: volvo877, Romtek
  
> Чтение/запись символа в любой точке экрана, в текстовом режиме
    Как записать/считать символ в любой точке экрана?


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

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

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

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

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

    ExpandedWrap disabled
          GoToXY(1, 24);
          InsLine;


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

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

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

    ExpandedWrap disabled
      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. Существует ещё один способ записать/считать символ с экрана - это прямая работа с видеопамятью, но об этом в моей следующей статье...
    user posted image
      А ещё
      ExpandedWrap disabled
        {выводит символ в заданном месте, заданного цвета и фона}
        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;
        Объявляешь тип:
        ExpandedWrap disabled
          type tscr=array[0..24,0..79,0..2]of byte;

        И пременную этого типа:
        ExpandedWrap disabled
          var scr:tscr absolute $B800:$0000;

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

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

        А если присвоить scr[5,5,1] знасение x, т.е.:
        ExpandedWrap disabled
          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 пишешь:
        ExpandedWrap disabled
          a:=scr[x,y,0];

        чтобы считать его атрибут:
        ExpandedWrap disabled
          b:=acr[x,y,1];
        В общем-то, в процессе работы системного программиста ему приходится 90% времени терять на отладку, т.к. сама отладка представляет собой рефлекторную алогичную последовательность действий, выработанную годами и представляющую собой замену "+" на "-". Логика появляется только после того, как программа заработает, и последующий день программист, изучая код, понимает, почему и как у него это получилось.
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script Execution time: 0,1475 ]   [ 17 queries used ]   [ Generated: 20.06.19, 05:12 GMT ]