Поделиться через


Обзор ввода мыши

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

Приложение получает входные данные мыши в виде сообщений, отправляемых или размещенных в его окнах.

В этом разделе описываются следующие темы:

Курсор мыши

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

Система поддерживает переменную, которая управляет скоростью мыши, т. е. расстояние курсора перемещается, когда пользователь перемещает мышь. Функцию SystemParametersInfo можно использовать с флагом SPI_GETMOUSE или SPI_SETMOUSE для получения или настройки скорости мыши. Дополнительные сведения о курсорах мыши см. в разделе "Курсоры".

Захват мыши

Система обычно отправляет сообщение мыши в окно, содержащее горячее место курсора при возникновении события мыши. Приложение может изменить это поведение с помощью функции SetCapture для маршрутизации сообщений мыши в определенное окно. Окно получает все сообщения мыши, пока приложение не вызовет функцию ReleaseCapture или не указывает другое окно захвата или пока пользователь не щелкает окно, созданное другим потоком.

При изменении записи мыши система отправляет WM_CAPTURECHANGED сообщение в окно, которое теряет запись мыши. Параметр lParam сообщения указывает дескриптор окна, который получает запись мыши.

Только окно переднего плана может записывать входные данные мыши. Когда фоновое окно пытается записать входные данные мыши, оно получает сообщения только для событий мыши, возникающих при горячей точке курсора в видимой части окна.

Запись входных данных мыши полезна, если окно должно получать все входные данные мыши, даже если курсор перемещается за пределы окна. Например, приложение обычно отслеживает положение курсора после события вниз кнопки мыши, следуя курсору, пока не произойдет событие мыши вверх. Если приложение не захватило входные данные мыши, а пользователь освобождает кнопку мыши за пределами окна, окно не получает сообщение "Кнопка вверх".

Поток может использовать функцию GetCapture , чтобы определить, запечатлела ли одна из окон мышь. Если одна из окон потока захватила мышь, GetCapture извлекает дескриптор в окно.

Мышь ClickLock

Функция специальных возможностей Mouse ClickLock позволяет пользователю заблокировать основную кнопку мыши после одного щелчка. В приложении кнопка по-прежнему нажимается вниз. Чтобы разблокировать кнопку, приложение может отправить любое сообщение мыши или пользователь может нажать любую кнопку мыши. Эта функция позволяет пользователю более просто выполнять сложные сочетания мыши. Например, те, у которых есть определенные физические ограничения, могут выделять текст, перетаскивать объекты или открывать меню проще. Дополнительные сведения см. в следующих флагах и примечаниях в SystemParametersInfo:

  • SPI_GETMOUSECLICKLOCK
  • SPI_SETMOUSECLICKLOCK
  • SPI_GETMOUSECLICKLOCKTIME
  • SPI_SETMOUSECLICKLOCKTIME

Конфигурация мыши

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

Windows поддерживает мышь с тремя кнопками. На трех кнопках мыши кнопки назначаются как левые, средние и правые кнопки. Сообщения и именованные константы, связанные с кнопками мыши, используют буквы L, M и R для идентификации кнопок. Кнопка мыши с одной кнопкой считается левой кнопкой. Хотя Windows поддерживает мышь с несколькими кнопками, большинство приложений используют левую кнопку в первую очередь и другие минимально, если вообще.

Приложения также могут поддерживать колесико мыши. Колесико мыши можно нажать или повернуть. При нажатии колесика мыши она выступает в качестве средней (третьей) кнопки, отправляя обычные сообщения о средней кнопке в приложение. При повороте сообщения колесика отправляются в приложение. Дополнительные сведения см . в разделе "Колесико мыши".

Приложения могут поддерживать кнопки команды приложения. Эти кнопки, называемые кнопками X, предназначены для упрощения доступа к интернет-браузеру, электронной почте и службам мультимедиа. При нажатии кнопки X в приложение отправляется сообщение WM_APPCOMMAND . Дополнительные сведения см. в описании сообщения WM_APPCOMMAND .

Приложение может определить количество кнопок мыши, передав SM_CMOUSEBUTTONS значение функции GetSystemMetrics. Чтобы настроить мышь для пользователя слева, приложение может использовать функцию SwapMouseButton для обратного значения кнопок мыши слева и вправо. Передача значения SPI_SETMOUSEBUTTONSWAP в функцию SystemParametersInfo — еще один способ изменить значение кнопок. Обратите внимание, что мышь является общим ресурсом, поэтому отмена значения кнопок влияет на все приложения.

XBUTTONs

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

Диспетчер окон поддерживает XBUTTON1 и XBUTTON2 через сообщения WM_XBUTTON* и WM_NCXBUTTON* . HIWORD WPARAM в этих сообщениях содержит флаг, указывающий, какая кнопка X была нажата. Так как эти сообщения мыши также подходят между константами WM_MOUSEFIRST и WM_MOUSELAST, приложение может фильтровать все сообщения мыши с помощью GetMessage или PeekMessage.

Следующая поддержка XBUTTON1 и XBUTTON2:

Следующие API были изменены для поддержки этих кнопок:

Вряд ли дочернее окно в приложении компонента сможет напрямую реализовать команды для XBUTTON1 и XBUTTON2. Поэтому DefWindowProc отправляет сообщение WM_APPCOMMAND в окно при нажатии кнопки X. DefWindowProc также отправляет сообщение WM_APPCOMMAND в родительское окно. Это похоже на то, как контекстные меню вызываются правой кнопкой мыши— DefWindowProc отправляет в меню WM_CONTEXTMENU сообщение, а также отправляет его родительскому элементу. Кроме того, если DefWindowProc получает сообщение WM_APPCOMMAND для окна верхнего уровня, он вызывает перехватчик оболочки с кодом HSHELL_APPCOMMAND.

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

Сообщения мыши

Мышь создает событие ввода, когда пользователь перемещает мышь, или нажимает или освобождает кнопку мыши. Система преобразует события ввода мыши в сообщения и отправляет их в очередь сообщений соответствующего потока. Когда сообщения мыши отправляются быстрее, чем поток может обрабатывать их, система удаляет все, кроме последнего сообщения мыши.

Окно получает сообщение мыши, когда происходит событие мыши, когда курсор находится в границах окна или когда окно запечатлело мышь. Сообщения мыши делятся на две группы: сообщения клиентской области и неклиентные сообщения. Как правило, приложение обрабатывает сообщения клиентской области и игнорирует неклиентные сообщения о области.

В этом разделе описываются следующие темы:

Сообщения мыши клиентской области

Окно получает сообщение мыши клиентской области при возникновении события мыши в клиентской области окна. Система отправляет сообщение WM_MOUSEMOVE в окно при перемещении курсора в клиентской области. Он публикует одно из следующих сообщений, когда пользователь нажимает или освобождает кнопку мыши, пока курсор находится в клиентской области.

Сообщение Значение
WM_LBUTTONDBLCLK Левая кнопка мыши дважды щелкалась.
WM_LBUTTONDOWN Нажата левая кнопка мыши.
WM_LBUTTONUP Выпущена левая кнопка мыши.
WM_MBUTTONDBLCLK Средняя кнопка мыши дважды щелкалась.
WM_MBUTTONDOWN Нажата средняя кнопка мыши.
WM_MBUTTONUP Была выпущена средняя кнопка мыши.
WM_RBUTTONDBLCLK Правая кнопка мыши дважды щелкалась.
WM_RBUTTONDOWN Нажата правая кнопка мыши.
WM_RBUTTONUP Выпущена правая кнопка мыши.
WM_XBUTTONDBLCLK Кнопка мыши X дважды щелкалась.
WM_XBUTTONDOWN Нажата кнопка мыши X.
WM_XBUTTONUP Выпущена кнопка мыши X.

 

Кроме того, приложение может вызвать функцию TrackMouseEvent , чтобы система отправляла два других сообщения. Он публикует сообщение WM_MOUSEHOVER при наведении курсора на клиентную область в течение определенного периода времени. Он публикует сообщение WM_MOUSELEAVE при выходе курсора из клиентской области.

Параметры сообщения

Параметр lParam сообщения мыши клиентской области указывает положение горячей точки курсора. Слово с низким порядком указывает координату x горячей точки, а слово с высоким порядком указывает координату y. Координаты указываются в координатах клиента. В клиентской системе координат все точки на экране указываются относительно координат (0,0) верхнего левого угла клиентской области.

Параметр wParam содержит флаги, указывающие состояние других кнопок мыши и клавиш CTRL и SHIFT во время события мыши. Эти флаги можно проверить, если обработка сообщений мыши зависит от состояния другой кнопки мыши или клавиши CTRL или SHIFT. Параметр wParam может быть сочетанием следующих значений.

значение Описание
MK_CONTROL Клавиша CTRL вниз.
MK_LBUTTON Левая кнопка мыши вниз.
MK_MBUTTON Средняя кнопка мыши вниз.
MK_RBUTTON Правая кнопка мыши вниз.
MK_SHIFT Клавиша SHIFT вниз.
MK_XBUTTON1 Первая кнопка X вниз.
MK_XBUTTON2 Вторая кнопка X вниз.

 

Дважды щелкните сообщения

Система создает сообщение двойного щелчка, когда пользователь дважды нажимает кнопку мыши в быстром последовательности. Когда пользователь нажимает кнопку, система устанавливает прямоугольник, центризуемый вокруг горячей точки курсора. Он также помечает время, в течение которого произошло нажатие. Когда пользователь нажимает ту же кнопку во второй раз, система определяет, находится ли горячее место в прямоугольнике и вычисляет время, истекшее с первого щелчка. Если горячее место по-прежнему находится в прямоугольнике и истекшее время не превышает значение времени ожидания двойного щелчка, система создает сообщение двойного щелчка.

Приложение может получать и задавать значения времени ожидания двойного щелчка с помощью функций GetDoubleClickTime и SetDoubleClickTime соответственно. Кроме того, приложение может задать значение времени ожидания двойного щелчка мыши с помощью флага SPI_SETDOUBLECLICKTIME с функцией SystemParametersInfo . Он также может задать размер прямоугольника, который система использует для обнаружения двойных щелчков, передав SPI_SETDOUBLECLKWIDTH и SPI_SETDOUBLECLKHEIGHT флаги в SystemParametersInfo. Обратите внимание, что установка значения времени ожидания двойного щелчка и прямоугольника влияет на все приложения.

По умолчанию определенное приложением окно не получает сообщения с двойным щелчком мыши. Из-за системных накладных расходов, связанных с созданием сообщений двойного щелчка, эти сообщения создаются только для окон, принадлежащих классам, имеющим стиль класса CS_DBLCLKS . Приложение должно задать этот стиль при регистрации класса окна. Дополнительные сведения см. в разделе "Классы окон".

Дважды щелкните сообщение всегда третье сообщение в четырех сообщениях. Первые два сообщения — это сообщения с кнопкой вниз и кнопкой, созданные первым щелчком. Второй щелчок создает сообщение двойного щелчка, за которым следует другое сообщение нажатой кнопки. Например, дважды щелкнув левую кнопку мыши, создается следующая последовательность сообщений:

  1. WM_LBUTTONDOWN
  2. WM_LBUTTONUP
  3. WM_LBUTTONDBLCLK
  4. WM_LBUTTONUP

Так как окно всегда получает сообщение вниз кнопки перед получением сообщения двойного щелчка, приложение обычно использует сообщение двойного щелчка для расширения задачи, которую она начала во время сообщения вниз кнопки. Например, когда пользователь щелкает цвет в цветовой палитре Microsoft Paint, краска отображает выбранный цвет рядом с палитрой. Когда пользователь дважды щелкает цвет, краска отображает цвет и открывает диалоговое окно "Изменить цвета ".

Неклиентные сообщения мыши области

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

Система создает сообщения неклиентной области в основном для собственного использования. Например, система использует сообщения неклиентной области для изменения курсора на двуглавую стрелку при перемещении горячей точки курсора в границу окна. Окно должно передавать неклиентные сообщения мыши в функцию DefWindowProc , чтобы воспользоваться встроенным интерфейсом мыши.

Существует соответствующее неклиентное сообщение мыши области для каждого сообщения мыши клиентской области. Имена этих сообщений похожи, за исключением того, что именованные константы для сообщений неклиентной области включают буквы NC. Например, перемещение курсора в неклиентной области создает сообщение WM_NCMOUSEMOVE и нажимает левую кнопку мыши, пока курсор находится в неклиентной области, создает сообщение WM_NCLBUTTONDOWN.

Параметр lParam сообщения мыши неклиентной области — это структура, содержащая координаты x-и y горячей точки курсора. В отличие от координат сообщений мыши клиентской области, координаты указываются в координатах экрана, а не в координатах клиента. В системе координат экрана все точки на экране относительно координат (0,0) верхнего левого угла экрана.

Параметр wParam содержит значение hit-test, указывающее, где в неклиентной области произошло событие мыши. В следующем разделе объясняется назначение значений hit-test.

Сообщение WM_NCHITTEST

Всякий раз, когда происходит событие мыши, система отправляет WM_NCHITTEST сообщение в окно, содержащее горячую точку курсора или окно, которое захватило мышь. Система использует это сообщение для определения того, следует ли отправлять клиентской области или неклиентное сообщение мыши. Приложение, которое должно получать сообщения мыши и кнопки мыши, должно передавать WM_NCHITTEST сообщение функции DefWindowProc.

Параметр lParam сообщения WM_NCHITTEST содержит координаты экрана горячей точки курсора. Функция DefWindowProc проверяет координаты и возвращает значение теста попадания, указывающее расположение горячей точки. Значение hit-test может быть одним из следующих значений.

Значение Расположение горячей точки
HTBORDER В границе окна, у которых нет границы размера.
HTBOTTOM В нижней горизонтальной границе окна.
HTBOTTOMLEFT В левом нижнем углу границы окна.
HTBOTTOMRIGHT В правом нижнем углу границы окна.
HTCAPTION В строке заголовка.
HTCLIENT В клиентской области.
HTCLOSE В кнопке "Закрыть ".
HTERROR В фоновом режиме экрана или в разделительной строке между окнами (аналогично HTNOWHERE, за исключением того, что функция DefWindowProc создает системный сигнал для указания ошибки).
HTGROWBOX В поле размера (аналогично HTSIZE).
HTHELP В кнопке справки.
HTHSCROLL На горизонтальной полосе прокрутки.
HTLEFT В левой границе окна.
HTMENU В меню.
HTMAXBUTTON В кнопке "Развернуть ".
HTMINBUTTON В кнопке "Свернуть ".
HTNOWHERE В фоновом режиме экрана или на разделительной линии между окнами.
HTREDUCE В кнопке "Свернуть ".
HTRIGHT В правой границе окна.
HTSIZE В поле размера (аналогично HTGROWBOX).
HTSYSMENU В меню "Система" или в кнопке "Закрыть" в дочернем окне.
HTTOP В верхней горизонтальной границе окна.
HTTOPLEFT В левом верхнем углу границы окна.
HTTOPRIGHT В правом верхнем углу границы окна.
HTTRANSPARENT В окне, в настоящее время охваченное другим окном в том же потоке.
HTVSCROLL В вертикальной полосе прокрутки.
HTZOOM В кнопке "Развернуть ".

 

Если курсор находится в клиентской области окна, DefWindowProc возвращает значение hit-test HTCLIENT в процедуру окна. Когда процедура окна возвращает этот код в систему, система преобразует координаты экрана горячей точки курсора в координаты клиента, а затем отправляет соответствующее сообщение мыши клиентской области.

Функция DefWindowProc возвращает одно из других значений хит-теста, когда горячая точка курсора находится в неклиентной области окна. Когда процедура окна возвращает одно из этих значений hit-test, система публикует сообщение мыши неклиентной области, помещая значение теста попадания в параметр wParam сообщения и координаты курсора в параметре lParam.

Сонар мыши

Функция специальных возможностей Mouse Sonar кратко показывает несколько концентрических кругов вокруг указателя, когда пользователь нажимает и освобождает клавиши CTRL. Эта функция помогает пользователю находить указатель мыши на экране, который загроможден или с разрешением, установленным на высокий, на мониторе низкого качества или для пользователей с нарушениями зрения. Дополнительные сведения см. в следующих флагах в SystemParametersInfo:

SPI_GETMOUSESONAR

SPI_SETMOUSESONAR

Мышь исчезает

Функция специальных возможностей Mouse Vanish скрывает указатель при вводе пользователя. Указатель мыши снова появится, когда пользователь перемещает мышь. Эта функция позволяет указателю скрыть типизированный текст, например в сообщении электронной почты или другом документе. Дополнительные сведения см. в следующих флагах в SystemParametersInfo:

SPI_GETMOUSEVANISH

SPI_SETMOUSEVANISH

Колесико мыши

Колесико мыши объединяет функции колесика и кнопку мыши. Колесо имеет дискретные равномерно пробелы. При повороте колеса сообщение колесика отправляется приложению по мере обнаружения каждого из них. Кнопка колесика также может работать как обычная кнопка середины Windows (третья). Нажатие и освобождение колесика мыши отправляет стандартные сообщения WM_MBUTTONUP и WM_MBUTTONDOWN . Дважды щелкнув третью кнопку, отправляет стандартное WM_MBUTTONDBLCLK сообщение.

Колесико мыши поддерживается с помощью сообщения WM_MOUSEWHEEL.

Поворот мыши отправляет сообщение WM_MOUSEWHEEL в окно фокусировки. Функция DefWindowProc распространяет сообщение на родительский элемент окна. Не должно быть внутреннего перенаправления сообщения, так как DefWindowProc распространяет его вверх по родительской цепочке до тех пор, пока окно, которое обрабатывает его.

Определение количества линий прокрутки

Приложения должны использовать функцию SystemParametersInfo , чтобы получить количество строк прокрутки документа для каждой операции прокрутки (колесиком). Чтобы получить количество строк, приложение выполняет следующий вызов:

SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, pulScrollLines, 0)

Переменная "pulScrollLines" указывает на целое число без знака, которое получает предлагаемое количество строк для прокрутки при повороте колесика мыши без клавиш модификатора:

  • Если это число равно 0, прокрутка не должна происходить.
  • Если это число WHEEL_PAGESCROLL, колесо должно быть интерпретировано как щелчок один раз на странице вниз или вверх по регионам полосы прокрутки.
  • Если число строк для прокрутки больше числа отображаемых строк, операция прокрутки также должна быть интерпретирована как операция вниз или вверх страницы.

Значение по умолчанию для числа линий прокрутки будет 3. Если пользователь изменяет количество строк прокрутки, используя лист свойств мыши в панель управления, операционная система передает сообщение WM_SETTINGCHANGE всем окнам верхнего уровня с указанными SPI_SETWHEELSCROLLLINES. Когда приложение получает сообщение WM_SETTINGCHANGE , оно может получить новое количество строк прокрутки путем вызова:

SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, pulScrollLines, 0)

Элементы управления, прокручиваемые

В таблице ниже перечислены элементы управления с функциями прокрутки (включая строки прокрутки, заданные пользователем).

Элемент управления Прокрутка
Изменение элемента управления Вертикальная и горизонтальная.
Элемент управления "Список" Вертикальная и горизонтальная.
Поле со списком Если не выпадает вниз, каждая прокрутка извлекает следующий или предыдущий элемент. При удалении каждый прокрутит сообщение в поле списка, которое прокручивается соответствующим образом.
CMD (командная строка) Вертикальный.
Структура в виде дерева Вертикальная и горизонтальная.
Представление списка Вертикальная и горизонтальная.
Прокрутки вверх и вниз Один элемент за раз.
Прокрутки панели отслеживания Один элемент за раз.
Microsoft Rich Edit 1.0 Вертикальный. Обратите внимание, что клиент Exchange имеет собственные версии элементов управления представлением списка и представления дерева, которые не поддерживают колесо.
Microsoft Rich Edit 2.0 Вертикальный.

 

Обнаружение мыши с колесикой

Чтобы определить, подключена ли мышь с колесиком, вызовите GetSystemMetrics с SM_MOUSEWHEELPRESENT. Возвращаемое значение TRUE указывает, что мышь подключена.

Следующий пример приведен в процедуре окна для элемента управления многострого редактирования:

BOOL ScrollLines(
     PWNDDATA pwndData,   //scrolls the window indicated
     int cLinesToScroll); //number of times

short gcWheelDelta; //wheel delta from roll
PWNDDATA pWndData; //pointer to structure containing info about the window
UINT gucWheelScrollLines=0;//number of lines to scroll on a wheel rotation

gucWheelScrollLines = SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 
                             0, 
                             pulScrollLines, 
                             0);

case WM_MOUSEWHEEL:
    /*
     * Do not handle zoom and datazoom.
     */
    if (wParam & (MK_SHIFT | MK_CONTROL)) {
        goto PassToDefaultWindowProc;
    }

    gcWheelDelta -= (short) HIWORD(wParam);
    if (abs(gcWheelDelta) >= WHEEL_DELTA && gucWheelScrollLines > 0) 
    {
        int cLineScroll;

        /*
         * Limit a roll of one (1) WHEEL_DELTA to
         * scroll one (1) page.
         */
        cLineScroll = (int) min(
                (UINT) pWndData->ichLinesOnScreen - 1,
                gucWheelScrollLines);

        if (cLineScroll == 0) {
            cLineScroll++;
        }

        cLineScroll *= (gcWheelDelta / WHEEL_DELTA);
        assert(cLineScroll != 0);

        gcWheelDelta = gcWheelDelta % WHEEL_DELTA;
        return ScrollLines(pWndData, cLineScroll);
    }

    break;

Активация окна

Когда пользователь щелкает неактивное окно верхнего уровня или дочернее окно неактивного окна верхнего уровня, система отправляет сообщение WM_MOUSEACTIVATE (среди прочего) в окно верхнего или дочернего. Система отправляет это сообщение после публикации сообщения WM_NCHITTEST в окно, но перед отправкой сообщения вниз по кнопке. При передаче WM_MOUSEACTIVATE функции DefWindowProc система активирует окно верхнего уровня, а затем отправляет сообщение вниз на верхний уровень или дочернее окно.

Обрабатывая WM_MOUSEACTIVATE, окно может управлять тем, становится ли окно верхнего уровня активным окном в результате щелчка мыши и получает ли окно, которое было щелкнуно, получает последующее сообщение вниз кнопки. Это делается путем возврата одного из следующих значений после обработки WM_MOUSEACTIVATE.

Значение Значение
MA_ACTIVATE Активирует окно и не удаляет сообщение мыши.
MA_NOACTIVATE Не активирует окно и не удаляет сообщение мыши.
MA_ACTIVATEANDEAT Активирует окно и удаляет сообщение мыши.
MA_NOACTIVATEANDEAT Не активирует окно, но удаляет сообщение мыши.

См. также

Использование преимущества перемещения мыши с высоким определением