Управление перемещением курсора
Необходимость перемещения курсора возникает при обработке тех событий,
которым в табл. 6.2 соответствуют коды от 4 до 7. Перемещение в чистом
виде вызывает только событие с кодом 4 — мышь движется, кнопка не нажата
и ее состояние не изменялось. Если же мышь движется при нажатой кнопке,
то кроме перемещения курсора могут выполняться и другие действия, например
"перетаскивание" объекта, на который указывает курсор.
Предварительные замечания
В зависимости от того, какая из кнопок является ведущей (обычно левая),
имя подпрограммы, выполняющей перемещение курсора, располагается на пятом
месте одного из списков choiceL или choiceR. Указывать это имя на пятом
месте обоих списков не имеет смысла. При обработке событий с кодами от
5 до 7 такой проблемы не возникает, поскольку предполагается, что одновременное
нажатие обеих кнопок в задачах не используется. Подпрограмма statms не
фиксирует этот случай, поскольку состояния кнопок анализируются независимо
друг от друга.
Для перемещения изображения курсора надо выполнить следующие действия
в такой последовательности: восстановить исходный фон на месте старого
изображения, вычислить адрес видеопамяти, соответствующий новому значению
координат, и вывести изображение курсора на новом месте (одновременно
сохранив исходный фон).
Перечисленные действия выполняет подпрограмма Motion,
текст которой приведен в примере 6.13. Кроме нее в текст примера включены
еще две подпрограммы, обращение к которым происходит из управляющего алгоритма
при нажатии оператором на клавиши с рисунками стрелок, направленных влево,
вправо, вверх и вниз. Подпрограмма Mothor перемещает
курсор на шаг вправо или влево, a Motver — вверх
или вниз. Шаг и направление перемещения задается в регистре bх, для перемещения
в сторону уменьшения значений координат его содержимое должно быть отрицательным
числом.
Подпрограммы Mother и Motver
являются вспомогательными, основные действия выполняет Motion.
Восстановление исходного фона и построение изображения курсора было
описано в разделе Немаскируемый курсор и разделе
Маскируемый курсор данной главы. Напомним только, что если вы предпочитаете
работать с немаскируемым курсором, то вместо подпрограмм Hidepnt
и showpnt надо использовать Tgipntr.
Способ пересчета значений координат в адрес видеопамяти уже неоднократно
обсуждался, остается только применить его в данном конкретном случае.
Мышь не всегда перемещается плавно, поэтому при вычислении адреса видеопамяти
не следует исходить из предположения, что курсор перемещается только в
одну из смежных точек, показанных в табл.
3.3. Текущие значения координат хранятся в переменных xpointer
(номер столбца) и Ypointer (номер строки), которые
описаны в примере 6.8. Для вычисления адреса номер строки умножается на
размер экрана по горизонтали (horsize), к произведению
прибавляется номер столбца и результат корректируется с учетом
Grunit. При этом предполагается, что код точки занимает 1 байт,
т. е. установлен один из режимов PPG.
Подпрограммы перемещения курсора. Таковы исходные предпосылки и теперь
можно обсудить особенности конкретной реализации подпрограммы Motion.
Ее текст приведен в примере 6.13.
Пример 6.13. Группа подпрограмм для перемещения курсора
Mothor: add Xpointer, bx изменение значения Xpointer
jmp short setpos обход следующей команды
Motver: add Ypointer, bx изменение значения Ypointer
setpos: mov ex, Xpointer сх = Xpointer
mov dx, Ypointer dx = Ypointer
Mouse 4 установка новых значений счетчиков
; Перемещение изображения j сказателя мыши на экране
Motion: call Hidepnt гасим курсор
mov ax, horsize помещаем в ах ширину экрана
mul Ypointer умножаем ах на номер строки
add ax, Xpointer прибавляем номер столбца
adc dx, 00 учитываем возможность переполнения
; В режимах direct color pезультат надо умножить на размер кода точки
mov Offspnt, ax сохраняем смещение в Offspnt
mov ax, GrUnit помещаем в ах значение GrUnit
mul dl вычисляем номер окна
add ax, Base win ! ! учитываем значение базового окна
mov Winpnt, ax сохраняем в Winpnt
call Showpnt рисуем изображение курсора
ret возврат из подпрограммы
Подпрограммы примера 6.13 рассчитаны на выполнение в режимах PPG. Если
вы будете использовать их в режимах direct color,
то результат полученный после выполнения команды adc
dx, oo надо умножить на размер кода точки. В тексте примера об
э.том напоминает комментарий.
В видеорежимах Hi-Color код точки занимает 2 байта. Для умножения на
2 после команды adc dx, oo надо вставить следующие команды:
shld dx, ax, 1 ; сдвиг dx с добавлением старшего разряда
ах
shl ах, 1 ; сдвиг содержимого ах на разряд влево
Первая команда сдвигает содержимое регистров dx:ax как одно двойное
слово, но изменяет только содержимое dx, в который
записывается старшая часть результата.
Поэтому для сдвига содержимого регистра ах нужна дополнительная команда.
В видеорежимах True color код точки занимает
4 байта. Для умножения на 4 в командах сдвига надо заменить 1 на 2.
shld dx, ax, 2 ; сдвиг dx с добавлением старших разрядов
ах
shl ax, 2 ; сдвиг содержимого ах на два разряда влево
Если код точки занимает три разряда (см. раздел),
то вместо сдвигов придется использовать умножение на 3.
Можно составить такой вариант программы, который учитывает размер кода
точки при выполнении сдвига. Этот размер формируется в процессе выполнения
подготовительных действий и хранится в специально выделенной переменной
wrdppnt (см. раздел). Подпрограмма
перемещения может работать либо с этой переменной, либо с дополнительным
параметром, содержащим величину сдвига.
Важно
Команда add ax, Base_win нужна, только если задача поддерживает работу
со страницами видеопамяти (см. раздел),
в остальных случаях ее надо исключить из текста примера.
Дополнительная точка входа
В описанной подпрограмме объединены восстановление исходного фона, вычисление
адреса видеопамяти и построение изображения курсора. Иногда эти действия
должны выполняться независимо друг от друга. Например, при перемещении
рисунка, на который указывает курсор, сначала восстанавливается исходный
фон, затем рисунок перемещается вслед за мышью и только после остановки
вычисляется адрес видеопамяти и выводится изображение курсора на новом
месте. Специально для подобных случаев можно предусмотреть вторую точку
входа в подпрограмму Motion.
Имя дополнительной точки входа указывается перед командой mov
ax, horsize. При входе через эту точку исключается удаление изображения
курсора с экрана Цель, сформулированная во введении к данному разделу,
достигнута. Мы описали управляющий алгоритм и набор подпрограмм, необходимых
для составления простейшей задачи, выполняющей перемещение курсора по
экрану в режиме опроса. Теперь можно перейти к рассмотрению более гибкого
управления перемещениями курсора.
|