Int 33h - Работа с мышью.
Наиболее распространенным устройством ввода графической информации в ПЭВМ является мышь. При перемещении мыши и/или нажатии/отпускании кнопок мышь передает информацию в компью-тер о своих параметрах (величине перемещения и статусе кнопок). Существует много различных типов устройства типа мышь, отличаю-щихся как по принципу работы (механическая, оптомеханическая и оптическая), так и по способу общения (протоколу) с ПЭВМ. Для достижения некоторой унификации каждая мышь поставляется обычно вместе со своим драйвером - специальной программой, по-нимающей данный конкретный тип мыши и предоставляющей неко-торый (почти универсальный) интерфейс прикладным программам. При этом вся работа с мышью происходит через драйвер, который от-слеживает перемещения мыши, нажатие и отпускание кнопок мыши и обеспечивает работу с курсором мыши - специальным маркером на экране (обычно в виде стрелки), дублирующим все передвижения мы-ши и позволяющим пользователю указывать мышью на те или иные объекты на экране.
Работа с мышью реализуется через механизм прерываний. При-кладная программа осуществляет прерывание 33h, передавая в регист-рах необходимые параметры, и в регистрах же получает значения, воз-вращенные драйвером мыши.
Приводим набор функций для работы с мышью в соответствии со стандартом фирмы Microsoft. Ниже приведены используе-мые файлы Mouse.h и Mouse.cpp.
// File Mouse.h #ifndef __MOUSE__ #define __MOUSE__ #define MOUSE_MOVE_MASK 0x01 #define MOUSE_LBUTTON_PRESS 0x02 #define MOUSE_LBUTTON_RELEASE 0x04 #define MOUSE_RBUTTON_PRESS 0x08 #define MOUSE_RBUTTON_RELEASE 0x10 #define MOUSE_MBUTTON_PRESS 0x20 #define MOUSE_MBUTTON_RELEASE 0x40 #define MOUSE_ALL_EVENTS Ox7F struct MouseState { int x, y; int Buttons; }; struct CursorShape { unsigned AndMask [16]; unsigned XorMask [16]; int HotX, HotY; }; typedef void ( *MouseHandler )( int, int, int, int ); int ResetMouse (); void ShowModseCursor (); void HideMouseCursor (); void ReadMouseState ( MouseState& ); void MoveMouseCursor ( int, int ); void SetMouseHorzRange ( int, int ); void SetraouseVertRange ( int, int ); void SetMouseShape ( CursorShapeA ); void SetHldeRange ( int, int, int, int ); void SetMouseHandler ( MouseHandler, int = MOUSE_ALL_EVENTS ); void RerooveMouseHandler (); #define ClearHideRange () ShowMouseCursor () #endif // File Mouse.cpp #include <alloc.h> #include "Mouse.h" #pragma inline static MouseHandler CurHandler = NULL; int ResetMouse () { asm { xor ax, ax int 33h } return _AX == OxFFFF; } void ShowMouseCursor () { asm { mov ax, 1 int 33h } } void HideMouseCursor () { asm { mov ax, 2 int 33h } } void ReadMouseState ( MouseState& s ) { asm { mov ax, 3 int 33h } #if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) asm { push es push di les di, dword ptr s mov es:[di ], cx mov es:[di+2], dx mov es:[di+4], bx pop di pop es } #else asm { push di mov di, word ptr s mov [di ], cx mov [di+2], dx raov [di+4], bx pop di } #endif } void MoveMouseCursor ( int x, int y ) { asm { mov ax, 4 mov cx, x raov dx, y int 33h } } void SetHorzMouseRange ( int xmin, int xmax ) { asm { mov ax, 7 mov cx, xmin mov dx, xmax int 33h } } void SetVertMouseRange ( int yrain, int ymax) { asm{ mov ax, 8 mov cx, ymin mov dx, ymax int 33h } } void SetMouseShape ( CursorShape& c ) { #if defined(__COMPACT ) || defined(__LARGE__) || defined(__HUGE__) asm { push es push di les di, dword ptr c mov bx, es:[di+16] mov cx, es:[di+18] mov dx, d'i mov ax, 9 int 33h pop di pop es } #else asm { push di mov di, word ptr c mov bx, [di+16] mov cx, [di+18] mov dx, di mov ax, 9 int 33h pop di } #endif } void SetHideRange ( int x1, int y1, int x2, int y2.) { asm { push si push di mov ax, 10h mov cx, x1 mov dx,y1 mov si, x2 mov di, y2 int 33h pop di pop si } } static void far MouseStub () { asm { push ds // preserve ds push ax // preserve ax mov ax, seg CurHandler mov ds, ax pop ax // restore ax push dx // у push cx // x push bx // button state push ax // event mask call CurHandler add sp, 8 // clear stack pop ds } } void SetMouseHandler ( MouseHandler h, int mask ) { void far *p = MouseStub; CurHandler = h; asm { push es mov ax, OCh mov cx, mask les dx, p int 33h pop es } } void ReraoveMouseHandler () { CurHandler = NULL; asm { mov ax, OCh mov cx, 0 int 33h } }
Инициализация и проверка наличия мыши
Функция ResetMouse производит инициализацию мыши и воз-вращает ненулевое значение, если мышь обнаружена.
Высветить на экране курсор мыши
Функция ShowMouseCursor выводит на экран курсор мыши. При этом курсор перемещается синхронно с перемещениями самой мыши.
Функция Hide Mouse Cursor убирает курсор мыши с экрана. Одна-ко при этом драйвер мыши продолжает отслеживать ее перемещения, причем к этой функции возможны вложенные вызовы. Каждый вызов функции HideMouseCursor уменьшает значение внутреннего счетчика драйвера на единицу, каждый вызов функции ShowMouseCursor уве-личивает счетчик. Курсор мыши виден только, когда значение счетчи-ка равно 0 (изначально счетчик равен -1).
При работе с мышью следует иметь в виду, что выводить изобра-жение поверх курсора мыши нельзя. Поэтому, если нужно произвести вывод на экран в том месте, где может находиться курсор мыши, сле-дует убрать его с экрана, выполнить требуемый вывод и затем снова вывести курсор мыши на экран.
Прочесть состояние мыши (ее координаты и состояние кнопок)
Функция ReadMouse State возвращает состояние мыши в полях структуры MouseState. Поля х и у содержат текущие координаты курсора в пикселах, поле Buttons определяет, какие кнопки нажаты. Установленный бит 0 соответствует нажатой левой кнопке, бит 1 -правой, и бит 2 - средней.
Передвинуть курсор мыши в точку с заданными координатами
Функция MoveMouseCursor служит для установки курсора мыши в точку с заданными координатами.
Установка области перемещения курсора
При необходимости можно ограничить область перемещения мы-ши по экрану. Для задания области возможного перемещения курсора по горизонтали служит функция SetHorzMouseRange, для задания об-ласти перемещения по вертикали - функция SetVertMouseRange.
Задание формы курсора
В графических режимах высокого разрешения (640 на 350 пиксе-лов и выше) курсор задается двумя масками 16 на 16 бит и смещением координат курсора от верхнего левого угла масок. Каждую из масок можно трактовать как изображение, составленное из пикселов белого (соответствующий бит равен 1) и черного (соответствующий бит равен 0) цветов. При выводе курсора на экран сначала на содержимое экра-на накладывается (с использованием операции AND_PUT) первая маска, называемая иногда AND-маской, а затем на то же самое место накладывается вторая маска (с использованием операции XOR_PUT). Все необходимые параметры для задания курсора мыши содержатся в полях структуры CursorShape. .Устанавливается форма курсора при помощи функции SetMouseShape.
Установка области гашения
Иногда желательно задать на экране область, при попадании в которую курсор мыши автоматически гасится. Для этого использу-ется функция SetHideRange. Но при выходе курсора из области гаше-ния он не восстанавливается. Поэтому для восстановления нормаль-ной работы курсора необходимо вызвать функцию ShowMouseCursor, независимо от того, попал ли курсор в область гашения или нет.
Установка обработчика событий
Вместо того, чтобы все время опрашивать драйвер мыши, можно передать драйверу адрес функции, которую нужно вызывать при на-ступлении заданных событий. Для установки этой функции следует воспользоваться функцией Set Mouse Handler, где в качестве первого параметра выступает указатель на функцию, а второй параметр задает события, при наступлении которых следует вызвать переданную функцию. События задаются посредством битовой маски. Возможные события определяются при помощи символических констант MOUSE_MOVE_MASK, MOUSE_LBUTTON_PRESS и других. Тре-буемые условия соединяются побитовой операцией ИЛИ, Передавае-мая функция получает 4 параметра - маску события, повлекшего за собой вызов функции, маску состояния кнопок мыши и текущие ко-ординаты курсора. По окончании работы программы необходимо обя-зательно убрать обработчик событий (при помощи функции RemoveMouseHandler).
Ниже приводится пример простейшей программы, устанавливаю- щей обработчик событий мыши на нажатие правой кнопки мыши и задающей свою форму курсора.
// File Example1. срр #include <bios.h> #include <conio.h> #include "Mouse.h" CursorShape с = { 0x0FFF, 0x07FF, 0x01FF, 0x007F, 0x801F, 0xC007, 0xC001, 0xE000, 0xE0FF, 0xF0FF, 0xF0FF, 0xF5FF, 0xF8FF, 0xFCFF, 0xFCFF, 0xFEFF, 0x0000, 0x6000, 0x7800, 0x3E00, 0x3F80, 0x1FE0, 0x1FF8, 0x0FFE, 0x0F00, 0x0700, 0x0700, 0x0300, 0x0300, 0x0100, 0x0100, 0x0000, 1,1 }; int DoneFlag = 0; void SetViOeoMode ( int mode ) asm { mov ax, mode int 1Oh } #pragma argsused void WaitPress (int mask, int button, int x, int у) { if (mask & MOUSE_R8UTTON_PRESS ) DoneFlag = 1; } main () { SetVideoMode ( 0x12 ); ResetMouse (); StiowMouseCursor (); SetMouseShape ( с ); SetMouseHandler ( WaitPress ); MoveMouseCursor ( 0, 0 ); while ( !DoneFlag ) HideMouseCursor (); ReraoveMouseHandler (); SetVideoMode ( 3 ); }
Оставить комментарий
Комментарии
//мышь на ассемблере
_asm{
mov ax, 4
mov cx, x
raov dx, y
int 33h };
выдает
1>c:\users\root\documents\visual studio 2008\projects\streamcapture\streamcapture\stream.cpp(116) : error C2443: operand size conflict
1>c:\users\root\documents\visual studio 2008\projects\streamcapture\streamcapture\stream.cpp(117) : warning C4405: 'dx' : identifier is reserved word
1>c:\users\root\documents\visual studio 2008\projects\streamcapture\streamcapture\stream.cpp(117) : error C2400: inline assembler syntax error in 'opcode'; found 'dx'