Программа 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, ®, ®);
if(reg.x.bx == 0)
{
printf("Mouse not found\n");
return -1;
}
// Подключаем драйвер событий, устанавливаем маску таким
// образом, чтобы драйвер вызывался при нажатии на левую
// или правую клавиши мыши
ms_seth(2 | 8, MS_HANDL);
// Включаем курсор
reg.x.ax = 1;
int86(0x33, ®, ®);
// Ожидаем вызова драйвера событий.
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,®,®,&segregs);
}