Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
54
Добавлен:
03.06.2014
Размер:
2.63 Mб
Скачать

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

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

Регистры на входе:

AX = 000Ch

CX = маска вызова;

ES:DX = адрес подключаемого драйвера событий

Регистры на выходе:

Регистры не используются

Биты маски вызова, передаваемой функции в регистре CX,определяют условие вызова драйвера событий:

Бит маски вызова

Когда выполняется вызов

0

Перемещение мыши

1

Нажатие левой клавиши

2

Отпускание левой клавиши

3

Нажатие правой клавиши

4

Отпускание правой клавиши

5

Нажатие средней клавиши

6

Отпускание средней клавиши

Если записать в регистр CX значение 7Fh, драйвер будет вызываться при возникновении любого события, а если 00h – драйвер будет отключен.

Адрес процедуры драйвера передается при вызове функции в регистровой паре ES:DX. Драйвер должен быть оформлен в виде процедуры типа FAR, завершающейся командой дальнего возврата RETF.

Когда драйвер получает управление, в регистрах процессора содержатся следующие значения:

Регистр

Описание

AX

Маска вызова, такая же, как и при вызове функции 0Ch

BX

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

бит 0 - левая клавиша;

бит 1 - правая клавиша;

бит 2 - средняя клавиша

CX

Координата X курсора мыши

DX

Координата Y курсора мыши

SI

Относительное перемещение мыши по горизонтали в миках

DI

Относительное перемещение мыши по вертикалив миках

DS

Сегмент данных драйвера мыши

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

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

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

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

ПрограммаMsdriver

Программа MSDRIVER иллюстрирует способ работы с драйвером событий.

Исходный текст драйвера событий, составленный на языке ассемблера, представлен в листинге 3.5.

Листинг 3.5. Файлmsdriver\handler.asm

;**

;.Name ms_handl

;.Title Драйвер событий

;

;.Descr Драйвер событий вызывается драйвером мыши,

; когда происходит какое-нибудь событие из числа

; заданных при установке драйвера событий.

; Функция не должна вызываться из программы

; пользователя, ее вызывает только драйвер мыши.

;

;.Proto void far ms_handl(void);

;

;.Params Не используются

;**

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, и т.д.

Исходный текст программы MSDRIVERпредставлен в листинге 3.6.

Листинг 3.6. Файлmsdriver\msdriver.с

// =====================================================

// Работа с драйвером событий

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW: http://www.glasnet.ru/~frolov

// или

// http://www.dials.ccas.ru/frolov

// =====================================================

#include <dos.h>

#include <stdio.h>

#include <conio.h>

union REGS reg;

struct SREGS segregs;

extern void far MS_HANDL(void);

void ms_seth(int mask, void (far *hand)());

// Флаг драйвера событий. При вызове драйвер событий

// запишет в эту переменную значение 1

unsigned MS_FLAG;

// Область для содержимого регистров на входе

// в драйвер событий.

unsigned MS_BX;

unsigned MS_CX;

unsigned MS_DX;

unsigned MS_SI;

unsigned MS_DI;

unsigned MS_DS;

int main (void)

{

MS_FLAG=0;

// Инициализируем мышь

reg.x.ax = 0;

int86(0x33, &reg, &reg);

if(reg.x.bx == 0)

{

printf("Mouse not found\n");

return -1;

}

// Подключаем драйвер событий, устанавливаем маску таким

// образом, чтобы драйвер вызывался при нажатии на левую

// или правую клавиши мыши

ms_seth(2 | 8, MS_HANDL);

// Включаем курсор

reg.x.ax = 1;

int86(0x33, &reg, &reg);

// Ожидаем вызова драйвера событий.

for(;;)

{

if(MS_FLAG)

{

printf("\nRegisters on driver entry:"

"\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("\nPress any key...");

getch();

return 0;

}

}

}

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);

}

Соседние файлы в папке несколько программ