Работа с мышью

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

Таблица 19

Сообщения, поступающие от мыши
  Сообщение Причина возникновения сообщения
  WM_LBUTTONDBLCLK Двойной щелчок левой клавишей мыши во внутренней области окна
  WM_LBUTTONDOWN Нажата левая клавиша мыши во внутренней области окна
  WM_LBUTTONUP Отпущена левая клавиша мыши во внутренней области окна
  WM_NCLBUTTONDBLCLK Двойной щелчок левой клавишей мыши во внешней области окна
  WM_NCLBUTTONDOWN Нажата левая клавиша мыши во внешней области окна
  WM_NCLBUTTONUP Отпущена левая клавиша мыши во внешней области окна
  WM_MOUSEMOVE Перемещение курсора мыши во внутренней области окна
  WM_NСMOUSEMOVE Перемещение курсора мыши во внешней области окна

Аналогичные 12 сообщения идут от правой и средней кнопок с префиксами WM_RBUTTON и WM_MBUTTON.

Таблица 20

Информация, передаваемая в сообщении от мыши
wParam значение, с помощью которого можно определить, какие клавишина мыши и клавиатуре были нажаты в тот момент, когда произошло событие, связанное с сообщением
LOWORD(lParam) горизонтальная позиция курсора мыши (физическая, ОКОННАЯ)
HIWORD(lParam) Вертикальная

Таблица 21

Значения wParam
Значение wParam Причина возникновения сообщения
MK_CONTROL На клавиатуре была нажата клавиша <Control>
MK_LBUTTON Была нажата левая клавиша мыши
MK_MBUTTON Была нажата средняя клавиша мыши
MK_RBUTTON Была нажата правая клавиша мыши
MK_SHIFT На клавиатуре была нажата клавиша <Shift>

Двойным щелчком (double click) называется пара одиночных щелчков, между которыми прошло достаточно мало времени.

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

Если выполнить двойной щелчок левой клавишей мыши в окне, для класса которого не определен стиль CS_DBLCLKS, функция окна последовательно получит следующие сообщения:

WM_LBUTTONDOWN - WM_LBUTTONUP - WM_LBUTTONDOWN - WM_LBUTTONUP

Если же сделать то же самое в окне, способном принимать сообщения о двойном щелчке, функция окна в ответ на двойной щелчок получит следующую последовательность сообщений:

WM_LBUTTONDOWN - WM_LBUTTONUP - WM_LBUTTONDBLCLK - WM_LBUTTONUP

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

Куда попадают сообщения от мыши?

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

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

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

HWND WINAPI SetCapture(HWND hWnd);

В режиме захвата все сообщения от мыши идут в окно с указанным идентификатором hWnd.

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

Освободить мышь – void WINAPI ReleaseCapture(void);

Эта функция не имеет параметров и не возвращает никакого значения.

Функция GetCapture позволяет определить идентификатор окна, захватившего мышь:

HWND WINAPI GetCapture(void);

Если ни одно окно не захватывало мышь, эта функция возвратит значение NULL.


Таймер

Существует объект, который с заданной частотой посылает сообщения WM_TIMER. Это сообщение низкоприоритетное. Оно посылается на обработку в том случае, если в очереди нет других сообщений.

Чтобы создать таймер, надо вызвать функцию SetTimer(hWnd, timer_id, nTimerout, tmProc).

Таблица 22

Параметры функции SetTimer
Параметр Описание
HWND hWnd таймер относится к этому окну
UINT timer_id идентификатор таймера, определим сами.
UINT nTimerout период посылки сообщений таймером, измеряется в мс
TIMERPROC tmProc функция таймера, обычно NULL. Она нужна, если надо, чтобы в нескольких окнах работал один таймер.

Чтобы удалить таймер, надо вызвать функцию KillTimer(hWnd, timer_id);

Для нагляности определим символьные идентификаторы таймеров.

#define ID_TIMER1 1

#define ID_TIMER2 2

Это часть функции окна, в котором будут работать таймеры.

case WM_CREATE://в момент создания главного окна создаем таймеры

SetTimer(hWnd,ID_TIMER1, 5, NULL);//создаем первый таймер

SetTimer(hWnd,ID_TIMER2, 1000, NULL);//создаем второй таймер

return 0;

case WM_TIMER: // сообщение от таймеров

//по wParam различаем таймеры

switch (wParam)

{

case ID_TIMER1: //выполняем действия, которые относятся к первому таймеру

break;

case ID_TIMER2: //выполняем действия, которые относятся ко второму таймеру

break;

}

case WM_DESTROY:);//окончание работы

KillTimer(hWnd, ID_TIMER1); // уничтожаем таймеры

KillTimer(hWnd, ID_TIMER2);

PostQuitMessage(0);

break;


Список литературы

1. Шилдт Г. Программирование на С и С++ для Windows 95, 1996.

2. Рихтер Дж. Windows для профессионалов. 4-е издание. – М.: Русская редакция Microsoft Press, 2004.

3. Румянцев П. В. Азбука программирования в Win32 API. – М.: Горячая Линия – Телеком, 2004.

4. Румянцев П. В. Работа с файлами в Win32 API. – М.: Горячая Линия – Телеком, 2002.

5. Верма Р. Справочник по функциям Win32 API. – М.: Горячая линия –Телеком, 2002.

6. Фролов А., Фролов Г. Операционная система Windows 95 для программиста

http://www.frolov-lib.ru/books/bsp.old/v22/index.html

7. http://msdn.microsoft.com/

8. http://www.firststeps.ru/mfc/winapi/win/apiwind1.html


Елена Александровна Кумагина


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: