прерывания int $33. Общий формат их вызова таков:
ASM
MOV AX, Number_Function
{...}
INT $33
END;
В отличии от остальных прерываний, функции которых определяются значением в регистре AH, прерывание INT $33 используют весь регистр AX.
Первой используемой в программе функцией этого прерывания должна быть функция $00 (инициализация мыши). Обычно эта команда используется только один раз - в самом начале программы. Для того, чтобы программы могли использовать мышь, предварительно необходимо загрузить драйвер. Этот драйвер обычно запускается командой в файле CONFIG.SYS или AUTOEXEC.BAT (В среде Windows драйвер мыши загружается согласно записи в реестре).
Ниже приведены основные термины, касающиеся мыши:
- пиксель - наименьший адресуемый элемент экрана.
- указатель мыши - в текстовом режиме это мерцающий прямоугольник в инверсном видеорежиме, в графическом режиме его вид может быть произвольным, но обычно это стрелка.
- микки(шаг) - наименьшее расстояние, перемещение на которое мышь может зарегистрировать (т.е. расстояние регистрируемое датчиками мыши). Обычно 0.125 мм.
- счетчик мыши - отсчитывает число микки (шагов), на которое мышь сместилась горизонтально или вертикально. Драйвер мыши отсчитывает эти перемещения и соответственно перемещает указатель мыши на экране.
- пороговая скорость - определенная скорость перемещения
(микки/с), при превышении которой скорость перемещения курсора по экрану удваивается. По умолчанию - 64 микки в секунду.
Инициализация мыши
Для инициализации мыши необходимо вызвать функцию $00. Эта функция должна вызываться первой из всех команд обработчика. Для ее вызова необходимо поместить в регистр AX значение $00 и вызвать прерывание INT $33.
Function InitMouse:boolean;
var
ResultRegAX:word;
begin
asm
mov ax,$00
int $33
mov ResultRegAX,ax
end;
If ResultRegAX=$FFFF then InitMouse:=true else InitMouse:=false
End;
Приведенная функция пробует инициализировать мышь, и если мышь инициализирована, возвращает true.
При инициализации, в регистр BX помещается количество кнопок у обнаруженной мыши. Поскольку не всегда требуется эта информация, можно вынести определение количества кнопок у мыши в отдельную функцию:
function ButtonMouse:byte;
var
ResultRegBX:word;
Begin
Asm
mov ax,$00
int $33
mov ResultRegBX,bx
End;
ButtonMouse:=ResultRegBX
end;
Функция возвращает количество кнопок у мыши. Эту функцию можно использовать в любом месте программы. (Это и есть тот случай, когда функцию $00 прерывания $33 вызывают второй раз).
При инициализации мыши, указатель не появляется на экране.
Отображение указателя мыши
Для отображения указателя мыши на экране, необходимо использовать функцию $01.
Драйвер мыши содержит флаг указателя, определяющий, должен ли указатель отображаться на экране. Указатель отображается, если флаг установлен в 0, и скрывается, если флаг установлен в любое другое значение. Изначально его значение -1. Функция $01 увеличивает его до 0, и курсор становится видим.
Procedure ShowMouse; assembler;
Asm
Mov AX,$01
Int $33
end;
Зарезервированное слово Assembler, которое было использовано в приведенной процедуре, указывает компилятору, что процедура целиком написана на ассемблере.
Cокрытие указателя мыши
Часто в процессе работы программы, требуется на время скрыть указатель мыши, например, при выводе графики. Для этого используют функцию $02.
Следующая процедура, при вызове, скрывает указатель мыши:
Procedure HideMouse; assembler;
Asm
Mov AX,$02
INT $33
End;
Перечисленные процедуры и функции можно так использовать в программе:
{...}
var
kolichestvoKnopok:byte;
{...}
begin
{...}
If InitMouse then
begin
{мышь инициализирована}
kolichestvoKnopok:=ButtonMouse;
ShowMouse;{отображение указателя}
{...}
HideMouse; {сокрытие указателя}
end else {мыши нет или не поддерживается}
{...}
Получение состояния мыши
Функция $03 позволяет получить данные о текущем состоянии мыши.
После вызова этой функции, в регистр BX помещается информация о состоянии кнопок, в регистр CX координата по горизонтали (х), а в регистр DX координата по вертикали (у)*(см. примечание!).
Следующая процедура возвращает координаты указателя.
Procedure GetMouseXY(VAR KoordX,KoordY:Word );
var
ResultCX,ResultDX:word;
begin
Asm
mov ax,$03
int $33
mov ResultCX,CX
mov ResultDX,DX
end;
KoordX:=ResultCX;
KoordY:=ResultDX
end;
При написании программ, очень часто нужно проверять не находится ли указатель в заданной прямоугольной части экрана. (например на кнопке).
Следующая процедура, возвращает true, если указатель находится в зоне x1,y1,x2,y2, где x1-левая граница зоны, x2 - правая граница, y1 - верхняя граница, y2 - нижняя граница.
Function MouseIn(X1,Y1,X2,Y2:word):boolean;
var
rdx,rcx:word;
begin
asm
mov ax,$03
int $33
mov rdx,dx
mov rcx,cx
end;
MouseIn := (rcx>=X1) and (rcx<=X2) and (rdx>=Y1) and (rdx<=Y2)
end;
Функция $03, как уже было сказано, возвращает состояние кнопок мыши.
Function ButtonPressed:byte;
var
rbl:byte;
begin
asm
mov ax,$03
int $33
mov rbl,bl
end;
ButtonPressed:=rbl
end;
Функция возвращает следующие значения:
- 1 - если нажата левая кнопка.
- 2 - если нажата правая кнопка.
- 3 - если нажаты левая и правая кнопки
- 4 - если нажата средняя кнопка (колесико)
- 5 - если нажаты левая кнопка и колесико
- 6 - если нажаты правая кнопка и колесико.
- 7 - если нажаты все кнопки (2 кнопки и колесико).
* все координаты исчисляются в пикселях!!! Даже в текстовом режиме!!! Поэтому для перемещения указателя мыши, скажем на 3 стоку, надо указать координату 8*3 = 24 (на одну строку в текстовом режиме идет 8 пикселей.
Установка указателя мыши в нужную позицию
Для установки указателя мыши в нужную позицию (X,Y) используйте следующую процедуру:
Procedure GotoMouseXY(x,y:word); assembler;
asm
mov ax,$04
mov cx,x
mov dx,y
end;
Не забудте умножить координаты на 8, если вы используете текстовый режим!
Регистрация события нажатия клавиши.
В модуль CRT включена очень полезная функция, возвращающая true, если была нажата клавиша, вот ее аналог для мыши. Функция возвращает true, если была нажата любая клавиша.
Function MousePressed: Boolean;
var
resultbx:word;
begin
asm
Mov ax, $03
Int $33
mov resultbx,bx
end;
MousePressed := resultbx<>0
end;
Определение количества нажатий клавиш
Для определения количества нажатия кнопок мыши используют функцию $05.
Следующая функция возвращает количество нажатий левой(при num=0), средней(при num=2),правой(при num=1) кнопкой мыши с момента последнего вызова данной процедуры. И еще они возвращают координаты мыши при последнем нажатии данной клавиши.
Function getnum(num:word; var x,y:word):word;
var
kn,ResultCX,ResultDX:word;
begin
asm
mov ax,$05
mov bx,num
int $33
mov ResultCX,cx
mov ResultDX,dx
mov kn,bx
end;
getnum:=kn;
x:=ResultCX;
y:=ResultDX
end;
Например, если надо получить координаты мыши при последнем нажатии левой кнопки мыши, достаточно вызвать процедуру так:
getnum(0,x,y);
Для такого вызова функции, включите расширенный синтаксис директивой
компилятору {$X+} или в настройках компилятора.
Пределы перемещения указателя Если в программе требуется ограничить область перемещения указателя, то для этого необходимо использовать функции $07 и $08.
Ограничение перемещения указателя по горизонтали.
Procedure LimHor(max,min:word); assembler;
asm
mov ax,$07
mov cx,min
mov dx,max
int $33
end;
Ограничение перемещения указателя по вертикали.
Procedure LimVer(max,min:word); assembler;
asm
mov ax,$08
mov cx,min
mov dx,max
int $33
end;
Чтение содержимого счетчиков перемещения мыши
эта операция возвращает величины смещения мыши по вертикали и горизонтали (в микки) со времени последнего вызова процедуры.
Procedure GetMikki(var x,y:integer);
var
RCX,RDX:word;
begin
asm
mov ax,$0B
int $33
mov RCX,cx
mov RDX,dx
end;
x:=RCX; y:=RDX
end;