Программирование на Паскале. Выпуск 10
В предыдущем выпуске я начал рассказывать, как на Паскале писать программы, работающие с мышью. Продолжим ...
Во-первых, убедитесь в том, что в оконном режиме указатель "виндовский", а в полноэкранном - "текстовый" прямоугольник. Переключаться между режимами лучше всего с помощью комбинации Alt + ENTER.
Теперь видоизменим программу. Заставим ее читать содержимое экрана по курсором мыши. Именно так и организована работа многих ДОСовские справочных систем. При этом мы, конечно, будем читать не с экрана, а из видеобуфера. Прочитанное слово будем на несколько секунд показывать внизу экрана.
Конечно, больше эффектов можно получить в графическом режиме. Но здесь могут появиться проблемы у Паскаля на хороших машинах. Если это и на Вашей будет, то напишите. Я изменю хотя бы последовательность рассказа.
Вот полный листинг программы. Скопируйте в окно редактора Borland Pascal и запустите, а я тем временем буду рассказывать, как она работает:
program mouse_02a; uses DOS, CRT; const WordChars: Set of Char = ['A'..'п','р'..'я']; procedure FillScreen; var f: File of char; c: Char; begin Assign(f, 'mou_02a.pas'); {$I-} Reset(f); {$I+} if IOResult <> 0 then Exit; ClrScr; While NOT EOF(f) do begin Read(f, c); Write(c) end; Close(f); end; procedure ShowStatusBar(mes: String); var buf: array[1..160] of byte; x, y: Integer; Attr: Byte; begin Move(ptr(SegB800, 24*160)^, buf, 160); x:=WhereX; y:=WhereY; Attr:=TextAttr; Attr:=$4e; GotoXY(1, 25); Write(copy(mes,1, 79)); GotoXY(x, y); TextAttr:=Attr; Delay(500); Move(buf, ptr(SegB800, 24*160)^, 160); end; function IntToStr(Int: Integer): String; var S: String; begin Str(Int, s); if length(s)=1 then s:='0'+s; IntToStr:=S end; function ReadWordAtPos(X_pos, Y_Pos: Integer): String; var S: String; i: Integer; begin S:=''; if chr(mem[SegB800:(Y_pos*80+X_Pos)*2]) in WordChars then begin S:=chr(mem[SegB800:(Y_pos*80+X_Pos)*2]); i:=-1; while chr(mem[SegB800:(Y_pos*80+X_Pos+i)*2]) in WordChars do begin s:=chr(mem[SegB800:(Y_pos*80+X_Pos+i)*2])+s; dec(i); end; i:=1; while chr(mem[SegB800:(Y_pos*80+X_Pos+i)*2]) in WordChars do begin s:=s+chr(mem[SegB800:(Y_pos*80+X_Pos+i)*2]); inc(i); end; end; if S = '' then S:='Нет слова'; ReadWordAtPos:=S end; var r: Registers; x, y: Word; BEGIN r.ax:=0; intr($33, r); if r.ax <> $FFFF then begin WriteLn('Мышь не обнаружена'); Halt(1) end; FillScreen; Write('Мышь обнаружена с ',r.bx,' кнопками'); r.ax:=1; intr($33, r); repeat r.ax:=3; intr($33, r); if r.bx and 1 <> 0 then begin x:=r.cx div 8; y:=r.dx div 8; r.ax:=2; intr($33, r); ShowStatusBar(IntToStr(x)+':'+ IntToStr(y)+' '+ReadWordAtPos(x,y)); r.ax:=1; intr($33, r); end; until KeyPressed or (r.bx and 2 <> 0); END.Сразу замечу, что эта программа, по-прежнему, не оптимальна. "Мышиное" прерывание (с номером $33) позволяет и даже ориентировано на использование процедуры - обработчика событий от мыши. То есть, сейчас мы принудительно, нужно это или нет, вызываем прерывание, чтобы определить не случилось ли чего. В принципе, это должно существенно тормозить работу системы.
Вместо этого можно создать процедуру, которую СИСТЕМА САМА будет вызывать только тогда, когда что-либо произойдет с мышью. Об этом я напишу позднее. Сейчас не будем торопиться.
Я добавил несколько подпрограмм, в которые "вынес" код, выполняющий конкретную группу действий. Это
В следующем выпуске я планирую рассказывать о мыши на графическом экране, в том числе и о спрайтовой мыши. Именно, такую чаще всего используют в играх
Свои вопросы и предложения присылайте Борису
Мы приглашаем Вас и Ваших друзей к сотрудничеству. Напишите, какая проблема Вас лично интересует - и мы постараемся помочь Вам. Поделитесь со всеми, если Вам удастся найти красивое решение. Присылайте свои программы, и если они хороши, то опубликуем их с обязательным указанием Вашего авторства.
По всем вопросам можно писать либо в Гостевую книгу нашего сайта на www.turbopascal.tk, либо
мне,
Постараюсь ответить на все вопросы и учесть все разумные предложения
Рассылка поддерживается сайтом www.turbopascal.tk. При перепечатке ссылка на сайт обязательна