Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Сообщения мыши, работа с мышью

 

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

WM_NCHITTEST 0                           y & x

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

WM_NCMOUSEMOVE                    wHitTest y & x

Если WM_NCHITTEST определяет, что курсор находится над внешней областью окна, то окно получает сообщения WM_NCMOUSEMOVE; Y и X координаты заданы относительно экрана.

WM_NCLBUTTONDOWN               wHitTest y & x
WM_NCLBUTTONUP wHitTest              y & x
WM_NCRBUTTONDOWN                        wHitTest y & x
WM_NCRBUTTONUP wHitTest              y & x
WM_NCMBUTTONDOWN                       wHitTest y & x
WM_NCMBUTTONUP wHitTest              y & x
WM_NCLBUTTONDBLCLK                    wHitTest y & x
WM_NCRBUTTONDBLCLK                    wHitTest y & x
WM_NCMBUTTONDBLCLK                   wHitTest y & x

Эти сообщения посылаются при нажатии/отпускании соответствующих кнопок мыши над внешней областью окна; Положение курсора указано в координатах экрана, wParam указывает зону, над которой произошло данное событие.

WM_MOUSEMOVE                          nKeys   y & x

Когда мышь перемещается во внутренней области окна (WM_NCHITTEST возвратило HTCLIENT) то оконная процедура обрабатывает поступающие сообщения WM_MOUSEMOVE, указывающие положение мыши в координатах окна и состояние некоторых клавиш (ctrl, shift и три кнопки мыши).

WM_LBUTTONDOWN                    nKeys   y & x
WM_LBUTTONUP   nKeys                   y & x
WM_RBUTTONDOWN nKeys                   y & x
WM_RBUTTONUP   nKeys                   y & x
WM_MBUTTONDOWN                             nKeys   y & x
WM_MBUTTONUP  nKeys                   y & x

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

WM_LBUTTONDBLCLK                nKeys   y&x
WM_RBUTTONDBLCLK                          nKeys   y&x
WM_MBUTTONDBLCLK                         nKeys   y&x

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

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

Вы можете легко изменять внешний вид курсора, изменяя его хендл в структуре класса окна:

UINT SetClassWord(hWnd, GCW_HCURSOR, hNewCursor);

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

HCURSOR    LoadCursor(hInstance, lpszCursor);

HCURSOR    CreateCursor(

hInstance, xHotSpot, yHotSpot, nWidth, nHeight, lpvAND, lpvXOR

);

BOOL   DestroyCursor(hCursor);

Функция LoadCursor загружает стандартный курсор или определенный Вами, CreateCursor создает новый курсор с помощью двух масок - lpvAND и lpvXOR, которые позволяют описать четырехцветный курсор - черный, белый, цвет фона, инвертированный фон. В применении этой функции есть только один “подводный камень” - ширина и высота создаваемого курсора должны совпадать с требованиями драйвера. Для этого их надо предварительно узнать с помощью функции

int         GetSystemMetrics(SM_CXCURSOR);

int         GetSystemMetrics(SM_CYCURSOR);

Функция DestroyCursor предназначена для уничтожения курсор, который Вы загрузили из собственных ресурсов или создали с помощью CreateCursor.

Вы можете легко показать или спрятать курсор с помощью функции

int         ShowCursor(bShow);

Вы можете установить или узнать позицию курсора с помощью функции

void SetCursorPos(nX, nY);

void GetCursorPos(lpPoint);

Также можно ограничить зону перемещения курсора с помощью функции

void ClipCursor(lpRect);

Еще одна функция,

HCURSOR    SetCursor(hCursor);

используется для задания хендла курсора, отображаемого в данный момент. Однако использовать ее надо осторожно, так как курсор является разделяемым ресурсом. Если Вы используете эту функцию, то Вы должны восстанавливать предыдущий курсор перед тем, как он покинет пределы внутренней области окна, или окно потеряет активность. Перед использованием этой функции надо убедиться, что хендл курсора, определенный для класса окон равен 0, что бы система не восстанавливала его прежний вид при каждом перемещении. Эту функцию удобно применять только в случае “захвата” курсора.

В некоторых случаях бывает удобно применять так называемый “захват” курсора. “Захваченый” курсор может перемещаться по всему окну, но сообщения от мыши поступают только в то окно, которое захватило курсор. При окно не получает сообщений WM_NCHITTEST, WM_NCMOUSEMOVE и пр., а получает сообщения как бы от внутренней области окна. Конечно, делать такое нужно на небольшое время, например для реализации механизма “Перенести и положить” (Drag And Drop). Только одно окно может захватывать курсор в данное время.

Для “захватывания” курсора предназначены следующие функции:

HWND SetCapture(hWnd);

void ReleaseCapture(void);

Функция SetCapture возвращает хендл предыдущего окна, использовавшего “захват” в это время, либо NULL.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...