68905

Мышь и таймер

Лекция

Информатика, кибернетика и программирование

Когда пользователь перемещает мышь операционная система перемещает по экрану растровую картинку обычно стрелку которая называется курсор мыши mouse cursor. Курсор мыши имеет вершину картинки hot spot размером в один пиксель...

Русский

2014-09-27

45.5 KB

0 чел.

Лекция 4

Мышь и таймер

 Общие сведения

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

bool fMouse = GetSystemMetrics(SM_MOUSEPRESENT);

int cButtons  = GetSystemMetrics(SM_CMOUSEBUTTONS);

Если мышь установлена, fMouse будет установлена в TRUE, количество кнопок при этом будет равняться cButtons.

Когда пользователь перемещает мышь, операционная система перемещает по экрану растровую картинку (обычно стрелку), которая называется "курсор мыши" (mouse cursor). Курсор мыши имеет "вершину" картинки (hot spot), размером в один пиксель, определяющую положение мыши на экране.

Ранее, при регистрации класса окна, мы уже сталкивались с необходимостью выбора типа курсора мыши, который устанавливается в приложении по умолчанию (см. тему "Регистрация окна"):

wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

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

IDC_APPSTARTING Стандартная стрелка с песочными часами

IDC_ARROW   Стандартная стрелка

IDC_CROSS   Крест

IDC_IBEAM   Текстовый курсор (в виде символа I)

IDC_ICON   Пустая иконка для Windows NT

IDC_NO   Перечеркнутая окружность

IDC_SIZE   Четыренаправленная стрелка для Windows NT

IDC_SIZENESW  

IDC_SIZENS   Различные стрелки изменения размера

IDC_SIZENWSE

IDC_SIZEWE

IDC_UPARROW

IDC_WAIT   Песочные часы ожидания

Сообщения мыши

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

Сообщение

Назначение

Значение параметра lParam

Значение параметра wParam

WM_MOUSEMOVE

Мышка перемещается над окном

Координаты мыши в координатах клиентской области окна:

x=

LOWORD(lParam)

y=

HIWORD(lParam)

Битовая маска, определяющая состояние управляющих клавиш и других кнопок мыши:

MK_LBUTTОN

     левая кнопка нажата

MK_RBUTTОN

            правая кнопка нажата

MK_МBUTTUN

            средняя кнопка нажата

MK_SHIFT

            <Shift> нажат

MK_CONTROL

            <Ctrl> нажат

WM_LBUTTONDOWN

Левая клавиша нажата

WM_MBUTTONDOWN

Средняя клавиша нажата

WM_RBUTTONDOWN

Правая клавиша нажата

WM_LBUTTONUP

Левая клавиша отпущена

WM_MBUTTONUP

Средняя клавиша отпущена

WM_RBUTTONUP

Правая клавиша отпущена

WM_LBUTTONDBLCLK

Левая клавиша дважды нажата

WM_MBUTTONDBLCLK

Средняя клавиша дважды нажата

WM_RBUTTONDBLCLK

Правая клавиша дважды нажата

 

Следует заметить, что окно состоит из двух частей – клиентской области (куда непосредственно осуществляется графический вывод оконной процедуры) и не клиентской области, которую занимает все оставшееся пространство окна (рамка, строка заголовка, меню). Сообщение от мыши приходит в оконную процедуру при попадании в любую область окна – клиентскую и не клиентскую. Тип сообщений в обоих случаях разный. Каждому сообщению в таблице, приведенной выше, соответствует сообщение не клиентской области имеющее префикс NC (nonclient). Например, WM_NCLBUTTONDOWN, WM_NCLBUTTONUP. Значения остальных параметров для не клиентской области отличаются: wParam показывает зону нерабочей области, в которой произошло перемещение или щелчок мыши (что можно определить при помощи идентификаторов, начинающихся с HT(hit-test) и определенных в заголовочных файлах Windows); параметр lParam содержит координаты мыши относительно экрана.

Существуют две функции, позволяющие перевести оконные координаты в координаты экрана и наоборот:

ScreenToClient(hwnd, pPoint); // преобразует экранные координаты в оконные

ClientToScreen(hwnd, pPoint); // преобразует оконные  координаты в экранные

В функции передаются координаты через структуру POINT. Функции преобразуют координаты и записывают новые их значения на место старых.

Захват мыши

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

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

Для захвата мыши используется функция:

SetCapture(hWnd);

После вызова этой функции, Windows посылает все сообщения мыши в оконную процедуру того окна, описателем которого является hWnd. Сообщения мыши в этом случае всегда будут оставаться сообщениями рабочей области, даже, если мышь перемещается в нерабочей области окна. Координаты мыши все равно передаются в оконных координатах, в связи с чем они могут принимать отрицательное значение (если мышь окажется выше или левее рабочей области окна). Для освобождения мыши программа обязательно должна вызвать функцию:

ReleaseCapture();

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

Таймер

Таймер в Windows является устройством ввода информации, которое периодически извещает о том, что истек заданный интервал времени. Ваша программа задает Windows интервал, через который приходят эти извещения.

Таймер используется в Windows в нескольких целях:

  •  Многозадачность – программа может использовать таймер для параллельного вызова подзадач.
  •  Поддержка обновления информации о состоянии программы и ее частей.
  •  Реализация авто сохранения.
  •  Завершение демонстрационный версий программ.
  •  Задания темпа изменения информации на экране.
  •  Программы мультимедиа
  •  и.т.п.

Аппаратно-программные сведения

Системная плата компьютера имеет микросхему таймера. ROM BIOS компьютера инициализирует эту микросхему так, чтобы она генерировала аппаратное прерывание. Это прерывание называют "тиком таймера". Они генерируются каждые 54,925 миллисекунды или примерно 18,2 раза в секунду. Таким образом, устанавливается правило: в обычной ситуации программа не может получать сообщения от таймера чаще, чем 18,2 раз в секунду. Далее вы научитесь устанавливать время срабатывания таймера для вашей программы. Так вот, исходя из ограничения на частоту, можно отметить, что ваша программа физически не может получать сообщения от таймера через интервал, меньший 55 миллисекунд.

Windows получает от таймера аппаратное прерывание (каждые 18,2 секунды). Все программы, использующие таймер, не могут использовать аппаратное прерывание (за исключением программ, работающих под  DOS и перехватывающих прерывания). Программы могут использовать таймер двумя способами: периодически получая сообщения от таймера WM_TIMER (фактически – от Windows) либо установив вызов какой либо процедуры приложения в зависимости от таймера. В первом случае, по истечению заданного интервала времени, Windows ставит в очередь сообщений к приложению синхронное сообщение WM_PAINT (это приводит к тому, что программа может получить сообщение несколько позже срока, а если, очередь сообщений переполнена, то и гораздо позже). Во втором случае, вы сообщаете Windows адрес своей процедуры и периодичность ее вызова. Все остальное Windows делает автоматически.

 

Программная реализация

Для настройки таймера на использование в вашей программе можно использовать функцию API SetTimer:

SetTimer(hwnd, ID_TIMERn, iMsecInterval, TimerProc);

где первый параметр определяет окно, оконная процедура которого будет получать сообщение WM_TIMER через каждые iMsecInterval миллисекунды, ID_TIMERn – идентификатор таймера (если ваша оконная процедура получает сообщения от нескольких таймеров, то по этому параметру можно определить от какого именно), TimerProc используется в том случае, когда периодически необходимо вызывать какую-либо функцию: тогда этот параметр является адресом функции.

Рассмотрим пример использования этой функции.

Пример 1.

Программе необходимо каждую секунду обновлять данные в окне приложения и каждую минуту выполнять авто-запись в файл.

#define ID_TIMER1 1

#define ID_TIMER2 2

void CALLBACK TimerProc(HWND hwnd, UINT Msg, UINT iTimerID, DWORD dwTimer)

{

// Запись информации на диск

}

int CALLBACK WndProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)

{

      .....

switch (Msg)

case  WM_CREATE:

SetTimer(hwnd, ID_TIMER1, 60000, (TIMERPROC)TimerProc);

SetTimer(hwnd, ID_TIMER2, 1000, NULL);

break;

 case  WM_TIMER:

   if (wParam == ID_TINER2) InvalidateRect(hwnd, NULL, FALSE);

  break;

 case WM_PAINT:

  . . . . . .

  break;

 case WM_DESTROY:

  KillTimer(hwnd, ID_TIMER1);

  KillTimer(hwnd, ID_TIMER2);

  break;

 . . . . . . . .

}

В данной программе устанавливаются два таймера во время прихода сообщения WM_CREATE. Первый из них устанавливает вызов процедуры TimerProc каждые 60000 миллисекунд, то есть каждую минуту. Установка второго таймера приводит к тому, что оконная процедура каждую секунду будет получать сообщение от таймера WM_PAINT, причем параметр wParam при этом будет содержать идентификатор таймера ID_TIMER2.

Обработка сообщения делает недействительной клиентскую область окна приложения, что автоматически приводит к посылке сообщения WM_PAINT.

При обработке сообщения WM_DESTROY приложение убивает установленные таймеры при помощи функции KillTimer, первый параметр которой определяет окно приложения, а второй – идентификатор таймера.

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


 

А также другие работы, которые могут Вас заинтересовать

83854. Хирургическая анатомия молочной железы. Лечение гнойного мастита 50.44 KB
  Хирургическая анатомия молочной железы Скелетотопия: между III и VI ребрами сверху и снизу и между окологрудинной и передней подмышечной линиями с боков. Дольки железы располагаются радиально вокруг соска. Лимфатическая система женской молочной железы и расположение регионарных лимфатических узлов представляют большой практический интерес в связи с частым поражением органа злокачественным процессом.
83855. Хирургическое лечение рака молочной железы. Лимфодиссекция 50.03 KB
  Хирургическое лечение рака молочной железы В хирургии рака молочной железы в настоящее время применяются следующие оперативные вмешательства: А. Мэйеру удаление молочной железы с опухолью единым блоком с малой и большой грудными мышцами и клетчаткой подкрыльиовой. Экономные: Радикальная мастэктомия с сохранением большой грудной мышцы по Пейти удаление молочной железы с опухолью единым блоком с малой грудной мышцей и клетчаткой подмышечной подключичной и подлопаточной областей с лимфатическими узлами.
83856. Хирургическая анатомия сердца, магистральные сосуды и клапаны сердца. Коронарные артерии 119.51 KB
  Хирургическая анатомия сердца Голотопия. Пространственная ориентация сердца и его отделов выглядит следующим образом. По отношению к срединной линии тела при мерно 2 3 сердца располагается слева и 1 3 справа.
83857. Принципы операций при врождённых и приобретённых пороках сердца 50.28 KB
  К врожденным порокам сердца относятся: дефект межпредсердной перегородки: дефект межже.тудочковой перегородки который приводит к сбросу крови в правый желудочек через дефект в мышечной или мембранозной части перегородки: незаращенный артериальный проток ductus rteriosus Боталлов. Дефект межпредсердной перегородки ушивание дефекта у больных с наличием легочной гипертензии или пластика перегородки заплатой из аутоперикарда синтетической ткани при большом диаметре дефекта. Дефект межжелудочковой перегородки: радикальная операция ...
83858. Хирургическая анатомия лёгких. Корень лёгкого 45.58 KB
  Сегмент участок легкого вентилируемый бронхом третьего порядка. На медиальной поверхности каждого легкого располагаются его ворота. Здесь находятся составляющие корень легкого анатомические образования: бронх легочные артерии и вены бронхиальные сосуды и нервы лимфатические узлы. Скелетотопически корень легкого располагается на уровне VVII грудных позвонков.
83859. Хирургическая анатомия полости груди. Техника пункции и дренирование плевральной полости 50.76 KB
  Техника пункции и дренирование плевральной полости. В грудной полости располагаются три серозных мешка: два плевральных и один перикардиальный. Между плевральными мешками в грудной полости расположено средостение в котором помещается комплекс органов куда входят сердце с перикардом грудная часть трахеи главные бронхи пищевод сосуды и нервы окруженные большим количеством клетчатки.
83860. Хирургическая тактика при проникающем ранении груди. Торакотомия. Обработка лёгочных артерий, лёгочных вен и бронхов 54.15 KB
  Гемоторакс скопление крови в полости плевры в результате повреждения кровеносных сосудов или стенки сердца. Диагностику проводят рентгенологически и с помощью пункции плевральной полости. Гемопневмоторакс скопление крови и воздуха в плевральной полости. Пневмоторакс скопление воздуха в плевральной полости в результате повреждения плевры.
83861. Лечение пневмоторакса 50.16 KB
  при повреждении париетальной плевры: внутренний при ране лёгкого или повреждении бронха т. при повреждении висцеральной плевры. закрытый однократное попадание воздуха и разобщение полости плевры с атмосферой; открытый постоянное сообщение плевральной полости с атмосферным воздухом во время вдоха воздух через рану проникает в плевральную полость а при выдохе выходит наружу: клапанный поступление воздуха только в плевральную полость изза наличия клапана нарастающее накопление воздуха в плевральной полости. Этапы помощи при...
83862. Долевое и сегментарное строение лёгких. Трахея и главные бронхи. Особенности лёгочных артерий и лёгочных вен 282.9 KB
  Длина трахеи 915 см ширина 1527 см. Место разветвления трахеи на два бронха получило название бифуркации трахеи. С внутренней стороны место разделения представляет собой вдающийся в полость трахеи полулунный выступ – киль трахеи. Главные бронхи асимметрично расходятся в стороны: правый более короткий 3 см но более широкий отходит от трахеи под тупым углом над ним залегает непарная вена; левый бронх длиннее 45 см более узкий и отходит от трахеи почти поп прямым углом над ним проходит дуга аорты.