Программирование на Паскале. Выпуск 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. При перепечатке ссылка на сайт обязательна