Мышь может порождать много сообщений, всего их 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 | Причина возникновения сообщения |
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
Елена Александровна Кумагина