CFA LogoCFA Logo Computer
Новости Статьи Магазин Драйвера Контакты
Новости
RSS канал новостей
В конце марта компания ASRock анонсировала фирменную линейку графических ускорителей Phantom Gaming. ...
Компания Huawei продолжает заниматься расширением фирменной линейки смартфонов Y Series. Очередное ...
Компания Antec в своем очередном пресс-релизе анонсировала поставки фирменной серии блоков питания ...
Компания Thermalright отчиталась о готовности нового высокопроизводительного процессорного кулера ...
Компания Biostar сообщает в официальном пресс-релизе о готовности флагманской материнской платы ...
Самое интересное
Программаторы 25 SPI FLASH Адаптеры Optibay HDD Caddy Драйвера nVidia GeForce Драйвера AMD Radeon HD Игры на DVD Сравнение видеокарт Сравнение процессоров

АРХИВ СТАТЕЙ ЖУРНАЛА «МОЙ КОМПЬЮТЕР» ЗА 2003 ГОД

Мысли о Паскале

Владислав ДЕМЬЯНИШИН nitromanit@mail.ru

Продолжение, начало см. в МК №46, 51-52, 4, 6-7, 10, 12-13, 16-18, 22, 24, 29, 34, 41, 46, 4, 6, 17, 21, 23 (165, 170-171, 175, 177-178, 181, 183-184, 187-189, 193, 195, 200, 205, 212, 217, 227, 229, 240, 244, 246).
Те читатели, которые внимательно следят за моими статьями, имели возможность убедиться, насколько легко можно расширять возможности языка Turbo Pascal, если не ограничиваться стандартными средствами и модулями.

Спрашивали? Отвечаю…

Дружба с Микки Маусом

Ну вот, выводить текст и получать информацию посредством ее ввода с клавиатуры мы уже научились. Все это хорошо, НО для создания программы с настоящим серьезным пользовательским интерфейсом необходима одна маленькая, но немаловажная деталь — работа с манипулятором «Мышь» (Mouse), а вернее, получение управляющих команд пользователя посредством интерфейса мыши и их обработка. Так вот, задача, которую мы сегодня перед собой поставим — это составление универсального модуля, который бы состоял из процедур и функций, позволяющих управлять манипулятором «мышь» и получать информацию о действиях пользователя (кликах и перемещении манипулятора). Своеобразный джентльменский набор самых необходимых процедур и функций.

Ну что же, начнем, как обычно, с блока Interface, описав в нем перечислимый тип TMouseButton для идентификации нажатой клавиши и множественный тип TMouseState, который послужит индикатором того, какая клавиша мыши нажата в данный момент. А так как одновременно могут быть нажаты несколько клавиш, рациональность применения множества в данном случае неоспорима.

Перейдя к блоку Implementation, опишем типизированную константу Ms_ButtonFlag, начальное значение которой свидетельствует о том, что ни одна клавиша мыши не нажата.

Теперь опишем короткую, но очень важную функцию Ms_Init, с выполнения которой нужно начинать работу программы, чтобы проверить наличие драйвера мыши в памяти. Будет возвращен результат true, если драйвер загружен, и false, если драйвер отсутствует или несовместим со стандартным интерфейсом, принятым Microsoft, но такое на моем веку не встречалось. Так что можно смело загружать драйверы mouse.com, mmouse.com, mouse.sys и другие, вручную или через autoexec.bat. Думаю, вас не нужно этому учить.

Функция состоит из двух машинных команд: mov ax,0 — загружает номер 0 функции инициализации драйвера мыши, а int 33h вызывает обработчик интерфейса мыши (драйвер), который, как правило, позиционируется на программном прерывании $33. При этом драйвер не только откликается и возвращает результат в регистре AX (AX = 0 — драйвера нет, или AX = $0FFFF — драйвер есть), но в регистре BX он может вернуть значение $0FFFF — стандартная мышь Microsoft с двумя клавишами, любое другое значение — мышь нестандартная. Но на это нам уже начхать :-).

Кроме того, драйвер осуществляет сброс аппаратного и программного обеспечения мыши. Т.е. все установки чувствительности и диапазона координат устанавливаются по умолчанию, курсор в центре экрана и невидим, видеостраница 0, работа пользовательского обработчика сообщений мыши заблокирована, чувствительность по горизонтали 8:8 микки/pixel, по вертикали — 16:8 микки/pixel, порог удвоения скорости равен 64 микки/сек.

Пример:

С этого момента можно обращаться к драйверу мыши. Наверное, первое, что может нас заинтересовать, это «Гюльчатай, покажи личико!» — то бишь курсор, ради которого мы все это затеяли. Для исполнения нашего желания следует вызвать процедуру Ms_CurShow, которую сейчас опишем:

Наверно, уже нет необходимости объяснять, что опять устанавливаем номер вызываемой функции и вызываем ее программным прерыванием $33. Скажу лишь, что функция под номером 1 отобразит (включит) курсор мыши, если при этом будет установлен стандартный текстовый или графический режим, коими являются текстовый режим 8025 и графические режимы CGA, EGA, VGA (разрешение последнего — 320200). Иначе, хотя и будет считаться, что курсор включен, он будет отображаться неправильно или не будет виден вовсе, так как, например, при VESA-режимах драйвер мыши не знает, как правильно рисовать курсор. Мы ему поможем, создав еще один модуль-надстройку, но это будет немного позднее.

Для осуществления собственной прорисовки курсора, например, программисту может понадобиться скрыть (выключить) курсор процедурой Ms_CurHide, которая вызывает функцию драйвера с номером 2.

При этом следует помнить, что если курсор мыши был выключен подряд определенное количество раз, чтобы его включить, следует столько же раз выполнить процедуру включения. Я так и вижу, как у некоторых читателей рука тянется к какому-нибудь тяжелому предмету, чтобы запустить в меня. Для тех, кто готов метнуть в меня камнем, скажу, что это придумал не я, а пресловутый Micro… Все камни прошу завернуть в яркую подарочную бумагу и послать посылкой в главный офис Microsoft, а лучше прямо на виллу резиденции гражданина Билла, как это делал кот Матроскин, посылая Шарику кочергу :-).

Особо любопытных могут заинтересовать функции Ms_X и Ms_Y, которые возвращают координаты курсора мыши в пикселях соответственно по горизонтали и вертикали. Даже если курсор мыши будет невидим, он все равно способен перемещаться, иначе зачем нам была бы нужна ента мышь белая :-)?

При этом вызывается функция 3 драйвера мыши, которая дает исчерпывающую информацию о положении курсора в регистрах CX — X, DX — Y и состоянии клавиш в регистре BX. Биты 0, 1 и 2 отвечают за левую (Left), правую (Right) и среднюю (Middle) клавиши соответственно, нулевое значение бита означает, что клавиша отпущена, а 1 — клавиша нажата. Но в данном случае, на мой взгляд, удобней читать координаты отдельно, а состояние клавиш отдельно. Хотя это и не рационально в смысле беспокойства для драйвера, но он не будет за это на нас в обиде.

Если возникнет непреодолимое желание установить курсор где-то в другом месте экрана, то в этом сможет помочь процедура Ms_SetPosition, которая позиционирует курсор мыши с новыми координатами X и Y, даже если он невидим. В итоге регистр CX будет загружен значением параметра X, а регистр DX — значением параметра Y, и будет вызвана функция 4 драйвера.

Тем, кто, читая мой талмуд, успел себе задать (риторический) вопрос «А где же у него кнопка?!…», внятный ответ сможет дать функция Ms_State, которая возвращает результат типа byte; последний можно легко привести к типу TMouseState путем нехитрой комбинации byte(MouseState):=Ms_State, где MouseState — переменная, заранее описанная с типом TMouseState.

Как вы могли заметить, в данном случае вызывается все та же функция драйвера 3, рассмотренная выше. Пример

иллюстрирует использование функции Ms_State. При нажатии левой клавиши (mbLeft) выполняется некоторое действие, а при нажатии правой (mbRight) цикл прекращается.

Основываясь на функции Ms_State, можно расширить функциональность модуля, описав функцию Ms_Down, которая позволяет определить, нажата ли затребованная клавиша Button в данный момент. Если да, то вернет true, если нет — false.

Тогда уже известный вам пример будет выглядеть гораздо нагляднее и эффективнее с точки зрения экономии памяти сегмента данных:

Вы со мной согласны? Не слышу? Ладно, молчание — знак согласия :-).

Следующая функция может помочь в отслеживании полного нажатия-отпускания клавиши (клик — Click). Достаточно лишь указать нужную клавишу, и функция вернет true, если клавиша была нажата и теперь отпущена, или false — если нет. Возможно, у кого-то возникнет вопрос: «А почему нельзя просто отследить отпускание клавиши? Ведь раз произошло отпускание, значит, было и нажатие». Дело в том, что если просто проверять состояние клавиши, то очень часто может фиксироваться факт, что клавиша отпущена, и тогда получится, что будет многократно опознано отпускание клавиши, даже когда это отпускание уже было обработано ранее. Именно для того чтобы устранить такое многократное срабатывание, и нужна функция Ms_Click. Правда, ее следует постоянно вызывать в теле некоторого цикла, чтобы не проморгать момент нажатия и отпускания клавиши. И тогда она зарегистрирует нажатие нужной клавиши в переменной Ms_ButtonFlag, а затем, при отпускании, сообщит нам.

Все тот же пример теперь будет выглядеть немного иначе:

Обычно чувствительность мыши по умолчанию вполне приемлема, но все же может возникнуть необходимость регулировать чувствительность мыши к перемещению. Для этого пригодится процедура Ms_SetMickey. Надо лишь задать величину, на сколько микки нужно передвинуть корпус мышки, чтобы переместиться на 8 точек по экрану по горизонтали и вертикали.

Таким образом, чем меньше величины параметров Horiz, Vertic, тем чувствительнее (быстрее) будет двигаться курсор, и наоборот, если установить эти величины очень большими, то, возможно, придется проехать мышкой полстола, чтобы добраться ее курсором до границы экрана :-).

В данном случае параметр Horiz загружается в регистр CX, а Vertic — в регистр DX, и вызывается функция $0f драйвера.

(Продолжение следует)

Литература:

1. Диалоговая справочная система Norton Guide.

Рекомендуем ещё прочитать:






Данную страницу никто не комментировал. Вы можете стать первым.

Ваше имя:
Ваша почта:

RSS
Комментарий:
Введите символы или вычислите пример: *
captcha
Обновить





Хостинг на серверах в Украине, США и Германии. © sector.biz.ua 2006-2015 design by Vadim Popov