Практикум программирования на C++ под Windows
comp.soft.prog.cppwin
Выпуск #11
2001-01-15
*** СОБЫТИЯ ОТ ВНЕШНИХ УСТРОЙСТВ ***********************************
Устройства ввода - клавиатура, мышь - служат источником внешних событий,
воспринимаемых системой. Какие-то из этих событий относятся и к нашей
программе. На каждое событие системой создается сообщение (message,
структура данных, описывающая событие), и помещается в очередь событий
(message queue) приложения. Сообщения забираются из очереди по одному - это
происходит в основном цикле обработки сообщений. После выборки очередного
сообщения из очереди (GetMessage) определяется окно, к которому направлено
это сообщение (DispatchMessage), и вызывается оконная процедура окна
(напр., MainWndProc).
Мышь
Любые действия с мышью, происходящие над нашим окном, приведут к появлению
набора сообщений со следующими именами:
Для последних двух сообщений есть версия для правой кнопки (WM_R...) и для
средней кнопки (WM_M..., используется крайне редко). При обработке этих
сообщений нас, как правило, интересует точка, в которой находится мышь.
case WM_MOUSEMOVE: //Действия при движении мыши
int x = LOWORD(lParam); //Координаты мыши в системе координат окна
int y = HIWORD(lParam);
if (wParam & MK_LBUTTON){ //Мышь движется с нажатой левой кнопкой
...
}
break;
Но если мы хотим отрисовать что-либо в обработчике мыши - даже просто
поставить точку, - придется откуда-то брать экран - а это уже
отрисовка по необходимости.
При работе с мышью часто используется прием "двойное нажатие" (double click).
При этом последовательно выполняется два нажатия кнопки мыши с коротким интервалом
между нажатиями. Это приводит к появлению сообщений (для левой кнопки):
WM_LBUTTONDOWN //Сначала происходит обычное нажатие
WM_LBUTTONUP
WM_LBUTTONDBLCLK //Второе нажатие опознается как двойное
WM_LBUTTONUP
Текущие координаты мыши можно получить в любой момент - функцией GetCursorPos.
Клавиши клавиатуры
Если наше окно активно, оно принимает сообщения о нажатиях клавиш:
WM_KEYDOWN Нажата клавиша либо автоповтор
WM_KEYUP Клавиша отпущена
Важнейший параметр здесь - сама клавиша - это параметр wParam. Его можно
сравнивать с константами VK_xxx (см. winuser.h):
case WM_KEYDOWN:
switch (wParam){
case VK_UP: ... break; //Обработка клавиши стрелка вверх
case VK_DOWN: ... break; // стрелка вниз
case VK_ESCAPE: ... break; // Esc
}
break;
При обработке сообщений клавиатуры и мыши бывает важно знать состояние
клавиш-регистров (Ctrl, Shift, Alt). В любом обработчике его можно получить
вызовом:
Нажатия алфавитно-цифровых клавиш кроме сообщений WM_KEYDOWN порождают
сообщения WM_CHAR. В случае, когда нас интересуют печатаемые символы
(например, в текстовом редакторе) мы можем обрабатывать их отдельно.
Если клавиша нажата в течение долгого времени, то система сама через равные
промежутки времени генерирует сообщения о нажатии - происходит автоповтор.
Можно выяснить, является ли клавиша реальным нажатием, или это только действие
автоповтора:
В том случае, когда в программе должно происходить продолжительное или
периодическое действие и при этом не должен теряться контроль над действиями
пользователя, мы используем такой ресурс как таймер. Таймер - это метроном,
подающий сигналы (сообщения или вызовы заданной функции) через равные
промежутки времени.
Как любой другой ресурс, таймер может быть создан и когда-нибудь он должен быть
удален:
UINT uTimer = SetTimer(hWnd, 1, 100, NULL); //Создаем таймер с номером 1
// для окна hWnd с интервалом 100 мс, посылающий сообщения WM_TIMER
... //Теперь 10 раз в секунду окну приходит сообщение WM_TIMER
KillTimer(hWnd, uTimer); //Уничтожаем таймер
Сообщения, приходящие от таймера, можно обрабатывать в оконной процедуре:
case WM_TIMER: //Квант продолжительного (периодического) действия
MessageBeep(-1); //Пищать 10 раз в секунду
...
break;
Упражнения
(Конечно, в каждом упражнении нужно написать программу, выполняющую
указанное)
1. Нажатие на левую кнопку мыши привдит к рисованию точки
2. Мышь при движении с нажатой левой кнопкой оставляет след
3. Из точки (0,0) к мыши тянется линия. При движении мыши линия тянется
за ней. (Используйте режим XOR для рисования и стирания линий)
4. При нажатой клавише пробел каждые полсекунды раздается звуковой сигнал
5. Программа завершается через 5 секунд после запуска
*** REAL LIFE ******************************************************
Помимо жизни виртуальной бывают у меня и радости в жизни реальной,
физической. Короче говоря, сын родился. В ночь на 14-ое января, вес 4kg,
рост 55cm. Звать Сашкой. Any questions?
Есть еще один вопрос, точнее просьба. Если вы хотите мне помочь, если вы
москвич, если ХОРОШО соображаете в железе и популярном юзерском софте -
будьте добры, напишите пожалуйста на мой e-mail. Нужен специалист -
настройщик компьютеров - для небольшой услуги. Заранее спасибо.
*************************************************************************
Количество подписчиков: 7996 Архив Рассылки