Установить драйвер событий



3.3.13. Установить драйвер событий

На входе: AX = 000Ch; CX = маска вызова: бит 0 - вызов при перемещении мыши; бит 1 - вызов при нажатии левой клавиши; бит 2 - вызов при отпускании левой клавиши; бит 3 - вызов при нажатии правой клавиши; бит 4 - вызов при отпускании правой клавиши; бит 5 - вызов при нажатии средней клавиши; бит 6 - вызов при отпускании средней клавиши; 7Fh - вызов при любом событии; 00h - отключение драйвера событий; ES:DX = адрес (дальний) подключаемого драйвера событий. На выходе: Регистры не используются.

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

Адрес подготовленной программы-драйвера передается при вызове функции в регистровой паре ES:DX. Драйвер должен быть оформлен в виде дальней процедуры, завершающейся командой дальнего возврата RETF. Когда драйвер получает управление, в регистрах процессора содержатся следующие значения: AX Маска вызова, такая же, как и при вызове функции0Ch. BX Состояние клавиш мыши: бит 0 - левая клавиша; бит 1 - правая клавиша; бит 2 - средняя клавиша. CX Горизонтальная координата курсора мыши. DX Вертикальная координата курсора мыши. SI Относительное перемещение мыши по горизонтали в миках. DI Относительное перемещение мыши по вертикали в миках. DS Сегмент данных драйвера мыши.



Так как регистр DS при вызове драйвера событий содержит сегмент данных драйвера мыши, ваш драйвер событий должен позаботиться о правильной установке этого регистра. Ваш драйвер событий не обязан сохранять и восстанавливать содержимое регистра DS и других регистров процессора.

Отметим, что если вам необходимо отключить драйвер, выполните повторный вызов функции 0Ch, записав в регистр CX нулевое значение. Если ваша программа, устанавливающая собственный драйвер событий, завершает свою работу и передает управление MS-DOS, предварительно она обязательно должна отключить драйвер событий.

Приведем функцию, которую мы разработали для подключения драйвера событий: /** *.Name ms_seth *.Title Установка драйвера событий * *.Descr Эта функция выполняет установку драйвера событий. * *.Proto void ms_seth(int mask, void (far *hand)()) * *.Params int mask - маска событий; * void (far *hand)() - адрес драйвера событий * *.Return Ничего * *.Sample ms_samp8.c **/ #include <dos.h> #include <conio.h> union REGS reg; struct SREGS segregs; void ms_seth(int mask, void (far *hand)()) { reg.x.ax = 0x14; reg.x.cx = mask; reg.x.dx = FP_OFF(hand); segregs.es = FP_SEG(hand); int86x(0x33,&reg,&reg,&segregs); }

Составление программы драйвера событий имеет некоторые особенности. Драйвер событий вызывается не из программы пользователя, а из драйвера мыши. При этом сегментный регистр DS будет указывать на сегмент данных драйвера мыши, а не на сегмент данных вашей программы.

Мы подготовили образец драйвера событий, использовав язык ассемблера: ;** ;.Name ms_handl ;.Title Драйвер событий ; ;.Descr Драйвер событий вызывается драйвером мыши, ; когда происходит какое-нибудь событие из числа ; заданных при установке драйвера событий. ; Функция не должна вызываться из программы ; пользователя, ее вызывает только драйвер мыши. ; ;.Proto void far ms_handl(void); ; ;.Params Не используются ; ;.Return Ничего ; ;.Sample ms_samp8.c ;** DOSSEG DGROUP GROUP _DATA _DATA SEGMENT WORD PUBLIC 'DATA' _DATA ENDS _TEXT SEGMENT WORD PUBLIC 'CODE' ASSUME cs:_TEXT, ds:DGROUP, ss:DGROUP ; Флаг вызова драйвера событий extrn _ms_flag:word ; Внешние переменные для записи содержимого регистров extrn _ms_bx:word extrn _ms_cx:word extrn _ms_dx:word extrn _ms_si:word extrn _ms_di:word extrn _ms_ds:word public _ms_handl _ms_handl proc far mov _ms_ds, ds ; Так как на входе в драйвер событий регистр DS указывает на ; сегмент данных драйвера мыши, устанавливаем его на сегмент ; данных программы; push ax mov ax, DGROUP mov ds, ax pop ax mov _ms_bx, bx mov _ms_cx, cx mov _ms_dx, dx mov _ms_si, si mov _ms_di, di ; Устанавливаем флаг вызова драйвера в 1, сигнализируя ; программе о том, что произошло событие. mov _ms_flag, 1 ret _ms_handl endp _TEXT ENDS END

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

Этот простейший вариант использования драйвера событий иллюстрируется следующей программой: #include <dos.h> #include <stdio.h> #include <conio.h> #include "sysp.h" extern void far ms_handl(void); // Флаг драйвера событий. При вызове драйвер событий // запишет в эту переменную значение 1. unsigned ms_flag; // Область для содержимого регистров на входе // в драйвер событий. unsigned ms_bx; unsigned ms_cx; unsigned ms_dx; unsigned ms_si; unsigned ms_di; unsigned ms_ds; int botm; main () { ms_flag=0; // Инициализируем мышь, определяем количество клавиш if(!ms_init(&botm)) { printf("\nМышь не установлена"); exit(-1); } // Подключаем драйвер событий, устанавливаем маску таким образом, // чтобы драйвер вызывался при нажатии на левую или правую // клавиши мыши. ms_seth(2 | 8, ms_handl); // Включаем курсор ms_on(); // Ожидаем вызова драйвера событий. for(;;) { if(ms_flag) { ms_off(); printf("\nСостояние регистров " "на входе драйвера:" "\nms_bx: %0X" "\nms_cx: %0X" "\nms_dx: %0X" "\nms_si: %0X" "\nms_di: %0X" "\nms_ds: %0X", ms_bx, ms_cx, ms_dx, ms_si, ms_di, ms_ds); printf("\nНажмите любую клавишу..."); getch(); exit(0); } } }

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

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



Содержание раздела