На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Название темы должно быть информативным !
Прежде чем задать вопрос, воспользуйтесь Поиском. и проверьте в FAQ (ЧАВО) Паскаля
Чтобы получить вразумительный ответ, подробно опишите проблему: что надо сделать, что не получается и номер ошибки (если есть), которую выводит компилятор.
Для вставки кода ваших программ используйте, пожалуйста, кнопку СODE=pas или выпадающий список СODE для других языков (подсветка синтаксиса).
[!] Как правильно задавать вопросы | Руководство по языку B.Pascal 7 & Objects/LR | Borland Pascal. Руководство пользователя
Модераторы: volvo877
  
> Резидент , Помогите
    Кто знает как написать резидента, который мог бы что-нибудь печатать в других прогах. Вообщем 'имитировал' нажатие клавиш. Все это естественно под MS-DOS huh.gif
    Сообщение отредактировано: Krishkinn -
      Давай напишем. Только что должно печататься? Какой, и когда это должно активироваться ?
        Это прога для экзаменов. Запускаешь её, указываешь номер билета, а она берет уже готовый исходник. Далее заходишь в Pascal нажимаешь на любые клавиши, а резидент пишит не то что нажато а готовый исходник.

        !!!Мне только надо узнать, как имитировать нажатие клавиш(отсылать в KEY-буфер нужную клавишу).
        Сообщение отредактировано: Krishkinn -
          Вот, но правда тут всё молодо, зелено %)) Нужно ещё дорабатывать. Лучше закоментируй пока строку keep, и поставь перед ней writeln (для тестирования).
          Я туда ещё много чего прифинтычу. Например буффер для текстовых данных. Ты скажи мне, какого максимум размера у тебя в билетах ответ ? Сколько мне памяти под прогу отводить ? или лучше читать из файла ? Тогда придётся самому писать чтение из файла. На асме (паскалевое не подойдёт). Хотя.. ммм.. хотя придумаем... главное время. А его у меня маловато свободного.

          Программа подменяет нажатия основных (не управляющих)клавиш на строку s2. Когда строка кончается Имитирует ENTER (#13). Поэтому тестировать лучше всего readln'ом
          ExpandedWrap disabled
            Program Resident;
            {Говорим компилятору, что все юниты имеют общий сегмент данных}
            {$G+}
            {Не будем использовать кучу}
            {$M 4072,0,0}
            uses dos;
            const
              Stacksize = 2*512; {512 - Количество слов в стеке}
              s2:string='Привет всем кто меня знает !!!'+#13;
              p:word=1;
            var
              oldint09:pointer;
              temp:word;
             
            {$F+}
            {Процедура обработки прерывания}
            procedure MyInt; Interrupt;
            begin
              asm
                jmp @skip
                db 14,'Мой резидент 2'
                @skip:
              end;
              temp:=memw[$0040:$001c];
              asm
                db $9c
                call oldint09
              end;
              if temp<>memw[$0040:$001c] then
              if((mem[$0040:memw[$0040:$001A]]<>0)and
                 (mem[$0040:memw[$0040:$001A]]<>224))
             
                 or(memw[$0040:memw[$0040:$001A]]=224) then
              begin
                mem[$0040:memw[$0040:$001A]]:=byte(s2[p]);
                if s2[p]='р' then mem[$0040:memw[$0040:$001A]+1]:=0;
                if p<length(s2) then inc(p);
              end;
            end;
            {$F-}
             
            var
              ptr1:pchar; {Указатель на предпологаемый резидент}
              s:string[14]; {Проверочная строка}
            begin
              getintvec($09,pointer(ptr1)); {Узнаем адрес вектора}
              {Скопируем из содержимого предпологаемого резидента проверочную строку}
              {Смещение - 18 это смещение проверочной строки от начала резидента}
              move(ptr1[18],s,15); {15 - количество букв + 1 байт на размер строки}
              if s='Мой резидент 2' then
              begin
                writeln('Программа уже запущена.');
                exit;
              end;
              GetIntVec($09,OldInt09);
              SetIntVec($09,Addr(MyInt));
              Keep(0);
            end.
            Я тут чуть изменил Ваш исходник. Теперь прога берет все из файла и печатает это. Также она включается/выключается при нажатии на '~'

            Program Resident;
            {Говорим компилятору, что все юниты имеют общий сегмент данных}
            {$G+}
            {Не будем использовать кучу}
            {$M 4072,0,0}
            uses dos;
            const
              Stacksize = 2*512; {512 - Количество слов в стеке}
              name='txt.txt';
              quit='~';
            var
              oldint09:pointer;
              temp:word;
              i,kolvo:longint;
              power:boolean;
              ch:char;
            {$F+}
            {Процедура обработки прерывания}
            procedure MyInt; Interrupt;
            begin
              asm
                jmp @skip
                db 14,'Мой резидент 2'
                @skip:
              end;
              temp:=memw[$0040:$001c];
              asm
                db $9c
                call oldint09
              end;
              if mem[$0040:memw[$0040:$001A]]=ord('~') then power:=not power;

              if power then
                if temp<>memw[$0040:$001c] then
                  if((mem[$0040:memw[$0040:$001A]]<>0)) then
                  begin
                    inc(kolvo);
                    reset(input);
                    i:=0;
                    while (ch<>#26)and(i<kolvo) do
                    begin
                      read(ch);
                      inc(i);
                    end;
                    close(input);
                    if ch=#26 then
                    begin
                      power:=false;
                    end else mem[$0040:memw[$0040:$001A]]:=ord(ch);
                  end;

            end;
            {$F-}

            var
              ptr1:pchar; {Указатель на предпологаемый резидент}
              s:string[14]; {Проверочная строка}
            begin
              assign(input,name);
              kolvo:=0;
              power:=false;
              getintvec($09,pointer(ptr1)); {Узнаем адрес вектора}
              {Скопируем из содержимого предпологаемого резидента проверочную строку}
              {Смещение - 18 это смещение проверочной строки от начала резидента}
              move(ptr1[18],s,15); {15 - количество букв + 1 байт на размер строки}
              if s='Мой резидент 2' then
              begin
                writeln('Программа уже запущена.');
                exit;
              end;
              GetIntVec($09,OldInt09);
              SetIntVec($09,Addr(MyInt));
              Keep(0);
            end.
              Нашёл два (как минимум) глюка:
              Во первых если в тексте программы, которую печатаем будет "~", то всё обрубится.
              Во вторых я убрал, а ты добавил глюк с русской буквой "р". Она не печатается. Для того, чтобы правильно её положить в буффер обмена, нужно в соседнюю ячейку буффера положить вместе с ней ноль (как было у меня): "if s2[p]='р' then mem[$0040:memw[$0040:$001A]+1]:=0;".

              И ты решил, что при нажатии любой клавиши (даже управляющей типа стрелок курсора) будет выводиться текст из файла. Чтож, это твоё решение %) Может так даже лучше. Я просто старался сделать так, чтобы текст выводился только при нажати на буквы, цифры, всякие знаки, но на стрелки и F клавиши не выводился бы %)
                Насчет первого глюка. Символ ~ никогда не встречается в исходниках Pascal.
                Насчет второго глюка. Эта ошибка возникает только с символом "р" или есть еще какие-нибудь символы?

                Заранее спасибо.
                  1. Не правда. Я вот проверял резидент на её собственном тексте. И там встретил такой символ %))))))))))
                  2. известный глюк. Только с этим символом. Его номер совпадает с кодом управляющих символов. И поэтому нужно проверять, и если сканкод (следующий байт в буффере клавиатуры) равен 0, а сама клавиша - "р" (кажется 229) то это буква "р". Иначе это управляющая клавиша. И, соответственно, если ты подменяешь клавиши, то для всех обычных букв тебе достаточно поменять один байт. А чтобы поместить в буффер букву "р" тебе нужно ещё сбросить в ноль следующий байт (как у меня в проге).
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0220 ]   [ 15 queries used ]   [ Generated: 5.05.24, 14:52 GMT ]