Общие сведения о вводе с помощью мыши

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

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

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

Курсор мыши

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

Система поддерживает переменную, которая управляет скоростью мыши, т. е. расстояние, в которое перемещается курсор, когда пользователь перемещает мышь. Вы можете использовать функцию 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 поддерживает мышь с несколькими кнопками, большинство приложений используют левую кнопку в первую очередь, а остальные — минимально, если вообще.

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

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

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

XBUTTON

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 не работает.

 

сообщения Double-Click

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

Приложение может получать и задавать значения времени ожидания двойного щелчка с помощью функций 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, Paint отображает выбранный цвет рядом с палитрой. Когда пользователь дважды щелкает цвет, Paint отображает его и открывает диалоговое окно Изменение цветов .

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

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

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

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

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

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

Сообщение WM_NCHITTEST

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

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

Значение Расположение горячей точки
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 возвращает значение HTCLIENT hit-test в процедуру окна. Когда оконная процедура возвращает этот код в систему, система преобразует координаты экрана курсора в клиентские координаты, а затем отправляет соответствующее сообщение мыши клиентской области.

Функция 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)

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

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

Control Прокрутка
Изменить элемент управления По вертикали и горизонтали.
Элемент управления "Список" По вертикали и горизонтали.
Поле со списком Если вниз нет, при каждой прокрутке извлекается следующий или предыдущий элемент. При откате вниз каждый из них перенаправит сообщение к списку, который прокручивается соответствующим образом.
CMD (командная строка) По вертикали.
Представление дерева По вертикали и горизонтали.
Режим списка По вертикали и горизонтали.
Прокрутка вверх и вниз По одному элементу за раз.
Прокрутки на панели дорожек По одному элементу за раз.
Microsoft Rich Edit 1.0 По вертикали. Обратите внимание, что клиент Exchange имеет собственные версии элементов управления представлением списка и представлением в виде дерева, которые не поддерживают wheel.
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 Не активирует окно, но удаляет сообщение мыши.

См. также раздел

Использование High-Definition перемещения мыши