На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! Правила ЧаВо (FAQ) разделов Паскаля
В этом разделе разрешено создавать только темы, в которых описано РЕШЕНИЕ какой-либо общей проблемы, или описание какого-либо аспекта языка Паскаль.
Обсуждение уже созданных тем разрешено, но только конструктивное, например указание на ошибку или уточнение имеющегося текста.

Также читать Требования к оформлению статей
Модераторы: volvo877, Romtek
  
> Программируем мышу., Все о работе с забавной зверушкой.
    Справка по программированию мыши.
    Да поможет она всем нуждающимся.


    Что здесь есть.
    Сначала идет общая информация, затем некоторое описание по программированию цветного анимированного указателя.


    Итак, общая теория.
    Поддержка мыши производится с помощью драйвера от небезызвестной фирмы Microsoft. Для доступа к драйверу используется прерывание $33. С помощью драйвера можно легко закодить мышь для текстовых режимов и черно - белый курсор 16X16 для низких разрешений графических режимов.

    Список известных мне функций прерывания (то, что записывается в регистр AX)..
    ExpandedWrap disabled
      $00 Сбросить установки драйвера.
      $01 Показать указатель.
      $02 Скрыть указатель.
      $03 Получить состояние мыши.
      $04 Переместить указатель.
      $05 Получить информацию о нажатиях кнопки.
      $06 Получить информацию об отпусканиях кнопки.
      $07 Установить границы перемещения по горизонтали.
      $08 Установить границы перемещения по вертикали.
      $09 Установить вид графического указателя.
      $0A Установить вид текстового указателя.
      $0B Получить относительное перемещение.
      $0C Установить условия вызова подпрограммы пользователя.
      $0D Включить эмуляцию светового пера.
      $0E Выключить эмуляцию светового пера.
      $0F Установить отношение числа шагов на единицу измерения экрана.
      $10 Установить область невидимости курсора.
      $13 Установить границу удвоения скорости перемещения.
      $14 Заменить подпрограмму пользователя.
      $15 Получить размер буфера, необходимый для сохранения состояния драйвера.
      $16 Сохранить текущее состояние драйвера.
      $17 Загрузить сохраненное состояние драйвера.
      $1D Установить видеостраницу мыши.
      $1E Получить видеостраницу мыши.
      $21 Получить информацию о драйвере мыши.
      $24 Получить информацию о мыши.

    Более подробное описание каждой функции в первом прикрепленном файле.


    Теперь несколько глубже.

    Для начала вкратце.
    1. Храни координаты курсора самостоятельно (в своих переменных). Аналогично можно хранить их предельные значения (MinX,MinY,MaxX,MaxY), даже нужно, если таковые существуют.
    2. Для хранения курсора лучше всего завести новый тип (Record). В нем будут содержаться HotX, HotY ("активная точка") и указатель на спрайт.
    3. Для перемещения курсора используй какую-нибудь процедуру (например, MoveMouse). Эта процедура будет стирать курсор из предыдущего положения, изменять его координаты и рисовать заново.
      • При рисовании не забывай записывать состояние экрана под курсором в буфер.
      • При стирании не забывай проверять соответствие номера активной видеостраницы и видеостраницы, на которой нарисован курсор.
      • Для изменения координат используй функцию $0B. Не забывай о предельных значениях.
      • Эту процедуру вполне можно установить, как пользовательскую подпрограмму для драйвера мыши.
    4. Можешь сделать, чтобы курсор рисовался на активной видеостранице, а можешь реализовать отдельную видеостраницу для мыши, при этом при рисовании курсора тебе придется проверять соответствие активной видеостраницы этой.
    5. Реализацию активной точки курсора тоже придется делать самостоятельно. Но это несложно: просто при выводе спрайта (и его стирании) нужно давать ему соответствующее смещение.
    6. Функции по сохранению состояния мыши придется реализовывать самостоятельно.

    Далее идут примеры со специализацией на TMT Pascal.
    Модуль, реализующий все это безобразие, смотри во втором прикрепленном файле.
    Немножко о его содержании.
    • Модульные файлы.
      • Images.pas - модуль для работы с картинками. Ему отведена отдельная тема: Работа с картинками
      • SprList.pas - модуль, реализующий обработку списков спрайтов. Его мы здесь обсуждать не станем, достаточно заглянуть в интерфейсную часть, чтобы понять, что он могёт.
      • GrMouse.pas - непосредственно интересующая нас штука - модуль для работы с мышкой, в общем, он как раз и показывает реализацию на конкретном языке того, о чем говорилось ранее.
    • Demo - простая демка этого модуля. Елозим по случайным образом закрашенному экрану указателем, пока не нажмем кнопку на клавиатуре.
    • Все файлы с расширением gmc - курсоры в поддерживаемом модулем формате.
    • Папочка cursors содержит слепки указателей в формате bmp.

    О формате курсоров.
    Каждый курсор представляет собой запись и хранит "активную точку" (поля HotX и HotY), список своих меняющихся спрайтов (поле images; собственно говоря, только для этого нужен SprList.pas) и количество смен в секунду (поле SPS). Это фактически достаточный минимум для анимированной мышки.

    Как осуществляется анимация.
    Ну, есть у нас так заданный курсор, попробуем теперь с ним поработать..
    Делается это не сложно, главное - знать когда где какой спрайт выводить и вовремя за собой очищать экран. Всю ответственность берет на себя процедура MoveMouse.
    В случае если курсор не показан (состояние изменяется посредством ShowMouse и HideMouse) все вообще просто - нужно только изменять координаты. Это делается через вызов функции, возвращающей относительное смещение.
    При включенном показе несколько сложнее. Но это как раз то, что нас интересует.
    • Стоит проверить, а нужно ли вообще перерисовывать курсор. Нужно, если имеет местечко хотя бы одно из событий: мышу подвигали или пора менять спрайт. Тогда придется работать.
    • Во-первых, рисование курсорчика. Если спрайт один, то особо мудрить нечего, достаточно почитать через координаты мышки и "активную точку" координаты изображения и вывести его. Если их несколько, то нужно выбирать какой выводить. Для этого нужно иметь таймер, который будет отсчитывать время с момента предыдущей смены спрайта, зная SPS, не сложно понять пора али нет. Смену умеет производить SpriteList, нас это не касается ;). Поменяли, вывели. Ура.
    • Теперь подумает о том, что за собой не плохо еще и убирать, т.е. не только рисовать спрайтики, но и стирать их, дабы не появлялись курсорные шлейфы по траектории полета указателя. Нам нужна переменная, в которую будем записывать содержимое экрана, попадающее под спрайт, перед тем как рисовать курсор. При стирании будем просто выводить это содержимое. Но! спрайты могут быть разных размеров, поэтому перед каждой их сменой следует очищать место, занятое этой переменной, и выделять новое исходя из габаритов активной картинки. Здесь нужно внимательно следить за возможностью возникновения "утечки памяти". :ph34r:
    Теперь это нужно удачно взаимоскомпоновать и все будет хорошо.

    Немного о получении координат.
    Для больших разрешений майкросовтовская версия такой функции работает, вообще говоря, некорректно. Зато есть другая, которая позволяет получить относительное смещение (отсчет ведется от предыдущего вызова этой функции, либо любой другой, возвращающей координаты курсора). Что будем делать: храним координаты сами, при вызове MoveMouse используем эту функцию, изменяем координаты и перерисовываем курсор.
    Хочу заметить, что неплохо и при получении координат передвигать мышку.
    Изменение координат, естественно, делается отдельной функцией. В ней нужно, если есть такое правило, проверять, не вылазит ли курсорчик за установленные границы, если вылазит, то присваивать плохой координате значение этой границы.

    Едем дальше - демка 1. Рисование ломаной.
    Смотри третий прикрепленный файл.
    Все просто до странности. Левой кнопкой отмечаем точки и заносим их координаты в очередь. Для этого в цикле:
    • Получаем координаты курсора (при этом он передвигается).
    • Если нажата левая кнопка, то скрываем курсор (дабы поверх него ничего не нарисовать), рисуем крестик с центром в точке с координатами курсора, сохраняем координаты, показываем курсор, ждем отпускания левой кнопки.
    До тех пор, пока не нажата правая кнопка.
    Далее по сохраненным координатам рисуем ломаную, последовательно соединяя отмеченные точки.

    Ну, и наконец - демка 2. Технология Drag&Drop.
    Угадай где искать пример :).
    Что, собственно говоря, такое Drag&Drop. Согласно Romtek'у
    Цитата
    Технология так и называется: "хватай и бросай": навели курсор на какой-то объект, нажимаем кнопку мыши, и, удерживая её в этом положении, переносим туда, где хотим "бросить". Там мышку и отпускаем.

    В этой программе будем использовать два курсора: обыкновенный и для перетаскивания прямоугольничка.
    Теперь о реализации перемещения прямоугольника. По сути, она очень напоминает обработку самого курсора. Только теперь скрываем сначала курсор, потом прямоугольник (курсор всегда выше), изменяем координаты прямоугольника (у курсора меняются при его перемещении), показываем прямоугольник и курсор.
    Итак, что делает программа. Пока не нажата правая кнопка повторяем:
    • Получаем координаты курсора (при этом он передвигается).
    • Если нажата левая кнопка, и курсор внутри прямоугольника, то начинаем его (прямоугольник) перетаскивать, а именно
      • Меняем курсор на перемещательный, предварительно скрыв его, а потом сразу показав.
      • Пока нажата левая кнопка, передвигаем прямоугольник - выполняем MoveRect.
      • Скрываем курсор и прямоугольник для получения цвета пикселя с координатами курсора.
      • Меняем цвет прямоугольника и показываем его.
      • Меняем курсор на обыкновенный и тоже показываем.
    Почему сделал выход правой кнопкой, не знаю, наверное, так удобно..


    На сим и хочу остановиться. Как всегда все вопросы и предложения принимаются и рассматриваются. ;)

    Содержимое архива:

    1 - functions.zip
    2 - GrMouse.zip
    3 - poly.zip
    4 - Drag&Drop.zip

    Прикреплённый файлПрикреплённый файлmouse.zip (37.4 Кбайт, скачиваний: 383)
    Эта волна мне по душе,
    Я люблю быть со всеми на ТЫ...
    (ЧайФ)

    Nokia 5800, S60v5
    mShell - как проще всего программировать для Symbian
    Все о Maemo (Nokia N900, Nokia N810...)
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script Execution time: 0,1204 ]   [ 17 queries used ]   [ Generated: 19.08.19, 18:49 GMT ]