МАНИПУЛЯТОР МЫШЬ

воскресенье, 25 апреля 2010 г. Автор: Vadim

Манипулятор мышь (в дальнейшем, просто мышь) является средством, позволяющим пользователю достаточно удобно осуществлять управление прикладными программами. Как правило, мышь соединена с ПЭВМ через последовательный интерфейс. Прикладные программы, связывающиеся через интерфейс с мышью, делают это через обращение к драйверу Microsoft, например GMOUSE.COM. Все обращения к драйверу происходят через прерывание 33h.

Прерывание 33h имеет ряд функций, которые выбираются с помощью загрузки номера функции в регистр AX. Основные функции будут приведены ниже.

Функция 00h: инициализация мыши. Если мышь инициализирована, то в регистре AX возвращается значение FFFFh, а в регистре BX - число клавиш мыши. Если инициализации не происходит, то в регистре AX возвращается значение 0000h.

Функция 01h: показать указатель мыши.

Функция 02h: спрятать указатель мыши.

Функция 03h: получить текущие координаты указателя мыши и состояние кнопок. Координаты указателя соответствует виртуальному экрану. На практике, обычно, они содержат положение пикселя в графическом режиме или умноженные на 8 координаты в текстовом режиме. Отсчет графических координат начинается от 0. Текстовые координаты отсчитываются от 1. Эта функция возвращает в регистре CX координату x, а в регистре DX координату y, в регистре BX - состояние кнопки (бит 0 - левая кнопка нажата, если установлена; бит 1 - средняя кнопка нажата, если установлена; бит 2 - правая кнопка нажата, если установлена).

Функция 04h: установить позицию указателя. В регистр CX пересылается координата x, а в регистр DX координата y. Установленная позиция указателя будет игнорироваться, если она находится внутри области исключения (см. функцию 07h и 08h). Координаты задаются всегда в пикселях, где (0,0) - координата верхнего левого угла виртуального экрана.

Функция 05h: получить информацию о нажатии клавиши. В регистр BX пересылается номер кнопки (0 - левая кнопка, 1 - правая кнопка, 2 - средняя кнопка). В регистр AX возвращается состояние кнопки (бит 0 - левая кнопка нажата, если установлена; бит 1 - средняя кнопка нажата, если установлена; бит 2 - правая кнопка нажата, если установлена). В регистр BX возвращается счетчик нажатия клавиши, CX - координата x последнего нажатия, DX - координата y последнего нажатия. После обращения к этой функции счетчик нажатия клавиши сбрасывается.

Функция 06h: получить информацию об отжатии клавиши. В регистр BX пересылается номер кнопки (0 - левая кнопка, 1 - правая кнопка, 2 - средняя кнопка). В регистр AX возвращается состояние кнопки (бит 0 - левая кнопка отжата, если установлена; бит 1 - средняя кнопка отжата, если установлена; бит 2 - правая кнопка отжата, если установлена). В регистр BX возвращается счетчик отжатий клавиши, CX - координата x последнего отжатия клавиши мыши, а DX - координата y последнего отжатия клавиши мыши. После обращения к этой функции счетчик отжатия клавиши сбрасывается.

Функция 07h: установить горизонтальное ограничение для указателя мыши. В регистр CX пересылается минимальное значение координаты x, в регистр DX - максимальное значение координаты x.

Функция 08h: установить вертикальное ограничение для указателя мыши. В регистр CX пересылается минимальное значение координаты y, в регистр DX - максимальное значение координаты y.

Функция 09h: установить форму указателя мыши в графическом режиме. По умолчанию используется указатель типа стрелки. В ES:DX пересылают адрес буфера изображения. Длина буфера изображения 64 байта. Байты с 32 по 64 определяют вид курсора, а байты с 0 по 31 определяют прозрачность курсора. Они рассматриваются как битовая маска 16´16 каждый бит которой маскирует пиксели экрана. При создании изображения драйвер предварительно получает информацию о 16´16 пикселях соответствующего места экрана и к каждому пикселю применяется операция AND с маской экрана, а затем к полученному результату - операция XOR с маской изображения. Приведенный ниже пример показывает формирование курсора в графическом режиме в виде прямоугольника с тонкой прозрачной полоской в середине.

program testmouse;

uses dos,graph;

var

reg:registers;

res1,res2,i,res3,res4:byte;

buf : array [0..63] of byte;

gd,gm:integer;

begin

FOR i:=32 TO 64 DO

buf[i]:=255;

FOR i:=0 TO 31 DO

buf[i]:=1;

gd:=detect;

initgraph(gd,gm,'');

reg.AX:=1;

intr($33,reg);

reg.ax:=9;

reg.es:=seg(buf);

reg.dx:=ofs(buf);

intr($33,reg);

.

.

.

closegraph;

end.

В регистр BX заносится смещение вправо (в пикселях) из левого верхнего угла указателя, пикселя изображения рассматриваемого драйвером в качестве текущей позиции. В регистр CX заносится смещение вниз (в пикселях) из левого угла указателя, пикселя изображения рассматриваемого драйвером в качестве текущей позиции.

Функция 0Ah: установить вид указателя мыши в текстовом режиме. В регистр BX заносят 0, если выбирают курсор, используемый в программе, и 1, если выбирают стандартный курсор. Если указатель генерируется программой, то в регистр CX заносятся биты определяющие маску AND, а в регистр DX заносятся биты определяющие маску XOR по следующему принципу. Биты 0-7 - код символа; биты 8-10 цвет символа; бит 11 - бит интенсивности; биты 12-14 - цвет фона; бит 15 - бит мерцания.

Функция 10h: установить область исключения указателя. В регистр CX пересылают значение левой верхней координаты x, в DX - значение левой верхней координаты y, в SI - значение правой нижней координаты x, в DI - значение правой нижней координаты y. Эта функция определяет область исключения отображения указателя мыши. Область исключения отменяется обращением к функции 00h или 01h, или другим обращением к этой функции.

Перед выполнением любых внешних программ, прикладные программы должны сохранять состояние драйвера мыши, для того, чтобы при возврате в прикладную программу все настройки мыши в прикладной программе оставались неповрежденными.

Функция 15h: получить размер сохраненного буфера состояния мыши. В регистр BX возвращается размер буфера в байтах.

Функция 16h: сохранить состояние драйвера мыши. В ES:DX заносится адрес буфера. Под буфер выделяется 64 байта.

Функция 17h: восстановить состояние драйвера мыши. В ES:DX заносится адрес буфера.

Функция 1Dh: установить текущую видеостраницу для указателя мыши. В регистр BX заносится номер видеостраницы. Допустимые номера страницы зависят от активного режима визуального отображения.

Функция 1Eh: получить текущую видеостраницу для указателя мыши. В регистр BX возвращается номер текущей видеостраницы для указателя мыши.

Функция 1Fh: отключить драйвер мыши. Если отключение драйвера прошло успешно, то в регистр AX заносится значение 001Fh, а в ES:BX - адрес драйвера. Если драйвер не отключен, то в регистр AX возвращается значение FFFFh.

Функция 20h: повторное включение драйвера мыши.

Функция 24h: получить информацию о мыши. Возвращаются следующие значения:

BH - старший номер версии драйвера; BL - младший номер версии драйвера; CH - тип мыши (1 - bus mouse, 2 - serial mouse, 3 - InPort mouse, 4 - PS/2 mouse, 5 - HP mouse); CL - номер аппаратного прерывания.

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

Procedure test;

{чтение мыши и клавиатуры}

type signal=record

case mouse:boolean of

true:(left,right:boolean;

{состояние клавиш мыши

dx,dy:word ;{ее перемещение });

false: (asc,ext:byte;

{ ASC- и расширенный коды }

status:word;

{флаги клавиатуры});

end;

{поле mouse показывает, сигнал от мыши или клавиатуры}

var ready:boolean;

begin

ready:=false; {ожидание команды}

with signal_t(signal) do

repeat

if mouse_sig then begin

mouse:=true;

r.ax:=11;intr($33,r);dx:=r.cx;dy:=r.dx;

r.ax:=3; intr($33,r);

left:=r.bx and 1 <>0;

right:=r.bx and 2 <>0;

mouse_sig:=false;

ready:=true; end

else {если мышь не трогали - опрос клавиатуры}

begin r.ah:=$11; intr($16,r);

{если не расширенная клавиатура, вызывайте функцию 1}

if r.flags and 64 = 0 then begin

{если буфер клавиатуры не пуст}

mouse:=false;

status:=memw[$40:$17]; {флаги клавиатуры}

repeat

r.ah:=$10;intr($16,r);

asc:=r.al; ext:=r.ah;

r.ah:=$11; intr($16,r);

ready:=r.flags and 64 <>0;

{очистка буфера и запоминание кода клавиши}

until ready; end;

end

until ready;

end;

Предлагаю ознакомиться с аналогичными статьями:



Отправить комментарий