МЫШЬ. Все о программировании мыши. |
МЫШЬ. Все о программировании мыши. |
Altair |
23.06.2004 7:31
Сообщение
#1
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Все операции, связанные с мышью, в программах выполняются посредством функций
прерывания int $33. Общий формат их вызова таков: ASM В отличии от остальных прерываний, функции которых определяются значением в регистре AH, прерывание INT $33 используют весь регистр AX. Первой используемой в программе функцией этого прерывания должна быть функция $00 (инициализация мыши). Обычно эта команда используется только один раз - в самом начале программы. Для того, чтобы программы могли использовать мышь, предварительно необходимо загрузить драйвер. Этот драйвер обычно запускается командой в файле CONFIG.SYS или AUTOEXEC.BAT (В среде Windows драйвер мыши загружается согласно записи в реестре). Ниже приведены основные термины, касающиеся мыши:
Инициализация мыши Для инициализации мыши необходимо вызвать функцию $00. Эта функция должна вызываться первой из всех команд обработчика. Для ее вызова необходимо поместить в регистр AX значение $00 и вызвать прерывание INT $33. Function InitMouse:boolean; Приведенная функция пробует инициализировать мышь, и если мышь инициализирована, возвращает true. При инициализации, в регистр BX помещается количество кнопок у обнаруженной мыши. Поскольку не всегда требуется эта информация, можно вынести определение количества кнопок у мыши в отдельную функцию: function ButtonMouse:byte; Функция возвращает количество кнопок у мыши. Эту функцию можно использовать в любом месте программы. (Это и есть тот случай, когда функцию $00 прерывания $33 вызывают второй раз). При инициализации мыши, указатель не появляется на экране. Отображение указателя мыши Для отображения указателя мыши на экране, необходимо использовать функцию $01. Драйвер мыши содержит флаг указателя, определяющий, должен ли указатель отображаться на экране. Указатель отображается, если флаг установлен в 0, и скрывается, если флаг установлен в любое другое значение. Изначально его значение -1. Функция $01 увеличивает его до 0, и курсор становится видим. Procedure ShowMouse; assembler; Зарезервированное слово Assembler, которое было использовано в приведенной процедуре, указывает компилятору, что процедура целиком написана на ассемблере. Cокрытие указателя мыши Часто в процессе работы программы, требуется на время скрыть указатель мыши, например, при выводе графики. Для этого используют функцию $02. Следующая процедура, при вызове, скрывает указатель мыши: Procedure HideMouse; assembler; Перечисленные процедуры и функции можно так использовать в программе:
Получение состояния мыши Функция $03 позволяет получить данные о текущем состоянии мыши. После вызова этой функции, в регистр BX помещается информация о состоянии кнопок, в регистр CX координата по горизонтали (х), а в регистр DX координата по вертикали (у)*(см. примечание!). Следующая процедура возвращает координаты указателя. Procedure GetMouseXY(VAR KoordX,KoordY:Word ); При написании программ, очень часто нужно проверять не находится ли указатель в заданной прямоугольной части экрана. (например на кнопке). Следующая процедура, возвращает true, если указатель находится в зоне x1,y1,x2,y2, где x1-левая граница зоны, x2 - правая граница, y1 - верхняя граница, y2 - нижняя граница. Function MouseIn(X1,Y1,X2,Y2:word):boolean; Функция $03, как уже было сказано, возвращает состояние кнопок мыши. Function ButtonPressed:byte; Функция возвращает следующие значения:
* все координаты исчисляются в пикселях!!! Даже в текстовом режиме!!! Поэтому для перемещения указателя мыши, скажем на 3 стоку, надо указать координату 8*3 = 24 (на одну строку в текстовом режиме идет 8 пикселей. Установка указателя мыши в нужную позицию Для установки указателя мыши в нужную позицию (X,Y) используйте следующую процедуру: Procedure GotoMouseXY(x,y:word); assembler; Не забудте умножить координаты на 8, если вы используете текстовый режим! Регистрация события нажатия клавиши. В модуль CRT включена очень полезная функция, возвращающая true, если была нажата клавиша, вот ее аналог для мыши. Функция возвращает true, если была нажата любая клавиша. Function MousePressed: Boolean; Определение количества нажатий клавиш Для определения количества нажатия кнопок мыши используют функцию $05. Следующая функция возвращает количество нажатий левой(при num=0), средней(при num=2),правой(при num=1) кнопкой мыши с момента последнего вызова данной процедуры. И еще они возвращают координаты мыши при последнем нажатии данной клавиши. Function getnum(num:word; var x,y:word):word; Например, если надо получить координаты мыши при последнем нажатии левой кнопки мыши, достаточно вызвать процедуру так: getnum(0,x,y); Для такого вызова функции, включите расширенный синтаксис директивой компилятору {$X+} или в настройках компилятора. Пределы перемещения указателя Если в программе требуется ограничить область перемещения указателя, то для этого необходимо использовать функции $07 и $08. Ограничение перемещения указателя по горизонтали. Procedure LimHor(max,min:word); assembler; Ограничение перемещения указателя по вертикали. Procedure LimVer(max,min:word); assembler; Чтение содержимого счетчиков перемещения мыши эта операция возвращает величины смещения мыши по вертикали и горизонтали (в микки) со времени последнего вызова процедуры. Procedure GetMikki(var x,y:integer); |
Altair |
23.06.2004 7:32
Сообщение
#2
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Область исключения указателя
Если в какой-то области экрана указатель мыши не должен отображаться, можно запретить это делать используя функцию $10 координаты x1,y1,x2,y2 - соответственно - левая граница(горизонт), гарница сверху, правая граница, нижняя. Procedure SetArea(x1,y1,x2,y2:word); assembler; Установка пороговой скорости Как уже отмечалось, пороговая скорость - скорость(микки/с) при превышении которой, указатель начинает перемещаться по экрану в 2 раза быстрее. Значение по умолчания - 64 микки/с Procedure SetSpeedMouse(mikkiS:word); assembler; Установка чувствительности мыши Чувствительность мыши - это минимальное расстояние в микки, ан которое нужно переместить мышь, чтобы указатель мыши на экране начал движение. Эта функция позволяет изменять чувствительность мыши отдельно по вертикали и горизонтали. Значения по умолчанию: Горизонтальная чувствительность 8 вертикальная чувствительность 16 пороговая скорость перемещения 64 (см. "установку пороговой скорости") Procedure SetMouseOptions(hor,ver,porog:word); assembler; Все перечисленные функции, удобно поместить в модуль. ----------------------------------------------------------------- Некоторые замечания.
Для использования этой процедуры, пропишите в разделе подключаемых модулей, модуль DOS. Эта процедура специально написанна без использования ассемблера, чтобы у Вас, читающих это, не возникло ощущения отсупления в этой теме, от Паскаля. Все предыдущие процедуры и функции тоже могут быть написанны на Паскале, без использования ассемблера (о переводе Паскаль <--> Ассемблер скоро появиться тема...) Здесь ScrCurMasc - это 64 байтный массив, определяющий маску экрана и маску указателя. x,y - смещение координатной точки относительно левого верзенго угла указателя. Попробуем создать свой указатель. Сразу скажу, что максимальный размер указателя - 16*16 пикселей. Для начала нам надо создать 64 байтный массив. Это делаеться следующим образом: первые 32 байта заполним единицами: const Теперь составляем вторую часть массива (тоже 32 байта ) Тут правило такое: (для удобства) распологаем по 2 столбика:
Теперь, если мы попробуем создать такой указатель: Var grDriver : Integer; (представленно в трудночитаемой форме, т.к. я это вырезал из окна TP.) Предварительно не забудте прописать uses dos,graph,crt; И описать константу a, как мы это уже сделали. На экране вы увидите белый квадрат 16*16 пикселей. Это получаеться следующим образом: первый столбец (из двух) в константе-массиве, это вторая часть указателя мыши!!! т.е. указатель:
нули здесь показывают вторую часть указателя мыши (описываеться первым столбцом в массиве!!!!). И наоборот, первая часть описывается вторым столбцом массива. Каждой число типа byte (эл-т массива) - это как раз 8 бит (как раз половина указателя). Т.е. для создания указателя придется пользоваться двоичной арифметикой. Проще всего запустить стандартный калькулятор в Windows, переключить его в инженерный вид, и в двоичную форму, записать нужное число и конвертировать его в десятичную или шестадцатиричную. Ну и в заключении, вот пример массива - маски, позволяющий создать указатель в виде восклицательного знака:
Если у Вас есть какие-либо вопросы, дополнения, или предложения, напишите сюда, или мне лично, на E-MAIL ( zharkih@list.ru ). |
Altair |
15.01.2005 12:23
Сообщение
#3
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
На основе вышеизложенной иформации, составлен модуль для работы с мышью.
скачать с pascal.dax.ru перейти на сайт. <div align="center">Краткое описание модуля:</div> Инициализация мыши Function InitMouse:boolean; Функция возвращает количество кнопок у мыши function ButtonMouse:byte; Отображение указателя мыши Procedure ShowMouse; Скрыть указатель Procedure HideMouse; Возвращаются координаты указателя Procedure GetMouseXY(VAR KoordX,KoordY:Word ); Возвращает true, если указатель находится в заданной области X1,Y1,X2,Y2 Function MouseIn(X1,Y1,X2,Y2:word):boolean; Следующая Функция возвращает следующие значения: 1 - если нажата левая кнопка. 2 - если нажата правая кнопка. 3 - если нажаты левая и правая кнопки 4 - если нажата средняя кнопка (колесико) 5 - если нажаты левая кнопка и колесико 6 - если нажаты правая кнопка и колесико. 7 - если нажаты все кнопки (2 кнопки и колесико). Function ButtonPressed:byte; Установка указателя мыши в позицию X, Y Procedure GotoMouseXY(x,y:word); Возвращает true, если была нажата любая клавиша. Function MousePressed: Boolean; Следующая функция возвращает количество нажатий левой(при num=0), средней(при num=2), правой(при num=1) кнопкой мыши с момента последнего вызова данной процедуры. Function getnum(num:word; var x,y:word):word; Ограничение перемещения указателя по горизонтали. Procedure LimHor(max,min:word); Ограничение перемещения указателя по вертикали. Procedure LimVer(max,min:word); возвращает величины смещения мыши по вертикали и горизонтали (в микки) со времени последнего вызова процедуры. Procedure GetMikki(var x,y:integer); Область исключения указателя координаты x1,y1,x2,y2 - соответственно - левая граница(горизонт), гарница сверху, правая граница, нижняя. Procedure SetArea(x1,y1,x2,y2:word); Установка пороговой скорости Значение по умолчания - 64 микки/с Procedure SetSpeedMouse(mikkiS:word); Установка чувствительности мыши procedure SetMouseOptions(hor,ver,porog:word); |
Altair |
20.01.2005 13:50
Сообщение
#4
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
FAQ ...
... Изменение вида курсора в графическом режиме. Альтернативный вариант - пишем свой драйвер на паскале. Одна из функций прерывания $33 -$0C служит для определения пользовательской процедуры, которая будет вызываться при возникновении прерывания $33 если буду выполнять условия, заданные в маске. Маска -это двоичное число, каждый бит которого представляет логическую функцию условия. маски: Цитата бит 0 вызов при перемещении мышки бит 1 вызов при нажатии левой кнопки бит 2 вызов при отпускании левой кнопки бит 3 вызов при нажатии правой кнопки бит 4 вызов при отпускании правой кнопки бит 5 вызов при нажатии средней кнопки бит 6 вызов при отпускании средней кнопки бит 7 зарезервирован (оставить 0) бит 8 зарезервирован (оставить 0) При выходе из прикладной программы все вызовы должны быть запрещены ( т.е. все биты должны равняться 0 ), иначе следующее прерывание мышки ( перемещения, нажатия на клавиши ) приведет к обращению к освободившейся памяти, что, как вы уже догадались, вызовет непредсказуемые последствия. ------------------------------------------------------------ Реализация. Я взял для демонстрации приема замены обработчика на свой - мой модуль, выложенный на сайте (ссылка выше). Немного изменим его. В секцию INTERFACE модуля, добавим вот такой код: const Это описание вида курсора. (примитивно...) и добавим процедуру Procedure SetMouseEventManager; Теперь в секцию IMPLEMENTATION добавим в самое начало: Var и внизу опишем процедуры (2 - одна из них открыта для использования в основной программе, другая - сам обработчик). Procedure SetMouseEventManager; Я привел код процедуры из модуля но с комментариями. ------------------------------------------------------------ ВАЖНО! Включите в настройках компилятора : Цитата 286 instructions ------------------------------------------------------------ Все остальное можете посмотреть в коде, который я присоединил к сообщению. Я не старался улучшить этот модуль, доведя этот способ замены обработчика до совершенства, так как вряд-ли это кому-то нужно... Все это лишь эксперименты... Как Вы наверно заметили, этот способ довольно сложен, т.к. требует написания обработчика почти исключительно на ассемблере. так например стоит нам попробовать вызвать процедуру writeln из обработчика, произойдет ошибка Run-Time Error 1795 - вообще недокументированная :) Одним словом, результат работы чуть неправильно составленного обработчика может быть непредсказуем. Тот код что я предоставил - стабилен, я его протестировал, но пока тестировал - Windows 2000 раз 6 останавливала работу эмулятора ДОС из-за разных ошибок. Это недостатки метода. Теперь преимущества метода. Теоретически, используя этот метод, можно выводить 16 цветные курсоры любой формы. Прикрепленные файлы MOUSE.PAS ( 5.77 килобайт ) Кол-во скачиваний: 1186 |
Текстовая версия | 28.10.2024 18:48 |