Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
WinAPI.docx
Скачиваний:
49
Добавлен:
16.12.2018
Размер:
3.43 Mб
Скачать

6.5 Захват мыши

Оконная процедура обычно получает сообщения мыши только тогда, когда курсор мыши находится в рабочей или в нерабочей области окна. Но программе может понадобиться получать сообщения мыши и тогда, когда курсор мыши находится вне окна. Если это так, то программа может произвести "захват" (capture) мыши.

6.5.1 Рисование прямоугольника

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

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

При нажатии левой кнопки мыши программа BLOKOUT1 сохраняет координаты мыши и первый раз вызывает функцию DrawBoxOutline. Функция рисует прямоугольник с использованием растровой операции R2_NOT, которая меняет цвет рабочей области на противоположный. При обработке последующих сообщений WM_MOUSEMOVE программа снова рисует такой же прямоугольник, полностью стирая предыдущий. Затем она использует новые координаты мыши для рисования нового прямоугольника. Наконец, когда программа BLOKOUT1 получает сообщение WM_LBUTTONUP, координаты мыши сохраняются, и окно делается недействительным, генерируя сообщение WM_PAINT для вывода на экран полученного прямоугольника.

В чем же проблема?

Попытайтесь сделать следующее: нажмите левую кнопку мыши внутри рабочей области окна программы BLOKOUT1, а затем переместите курсор за пределы окна. Программа перестает получать сообщения WM_MOUSEMOVE. Теперь отпустите кнопку. Программа не получит сообщение WM_LBUTTONUP, поскольку курсор находится вне рабочей области. Верните курсор внутрь рабочей области окна программы BLOKOUT1. Оконная процедура по-прежнему считает, что кнопка остается нажатой.

Это нехорошо. Программа не знает что происходит.

6.5.2 Решение проблемы — захват

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

Захватить мышь проще, чем поймать ее в мышеловку. Вам достаточно только вызвать функцию:

SetCapture(hwnd);

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

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

ReleaseCapture();

Эта функция возвращает обработку мыши в нормальный режим.

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

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]