![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
Я заметил одну вещь:
WM_LBUTTONUP посылается окну только если мышка отпущена в его области(на окне), а мне нужно как-то узнавать что мышка отпущена, где бы она ни была. Подскажите, как это сделать? |
|||
|
||||
SenkraD |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 3.2.2006 Где: Украина::Киев Репутация: 4 Всего: 23 |
||||
|
||||
nns2009 |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 174 Регистрация: 1.2.2009 Репутация: нет Всего: 1 |
Спасибо за ссылки, но правила я читал(и если б я не пользовался поиском, то моих сообщений было в два раза больше).
Ставить ловушки слишком заумно, а в моём случае буду считать, что если пользователь увёл мышку за пределы окна, то он её отпустил, в моём приложении это не слишком принципиально. Буду искать нужное событие. |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
т.е. WM_LBUTTONDOWN, все таки происходит в твоем приложении, т.е. тебе для своего приложения нужно узнавать что мышка отпущена? если так, то, хуки здесь не нужны, достаточно использовать механизм "захвата мыши": SetCapture и ReleaseCapture После вызова SetCapture, все мышиные сообщения начнут приходить в твое окно до тех пор, пока мышь не будет выпущена другим SetCapture или ReleaseCapture, независимо от того, проходит курсор по нему или нет. подробнее - смотри в поиск по этим ключам, тема не новая -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Capture - это слишком мощно, его захват "портит" логику многих процессов, иак что лучше не использовать всуе...
Разве что это свяано с тащением чего-либо или типа того, тогда да, Capture. В противном случае вопрос, насколько синхронно тебе нужно знать, что мышка вышла за пределы окна\отпустила кнопку. Если это нужно "не очень синхронно" - то поставь таймер и проверяй, не вышла ли мышь за пределы окна. Строго говоря, ставить таймер нужно, только если мышь приползла в окно (т.е. по первому MouseMove), а как только ты увидел (по таймеру), что мышь уползла - снимай. Диапазон подбери органолептически, чтобы хорошо смотрелось... Ну а если нужно синхронно - то только хук. И почему, собственно, хук слишком заумный? -------------------- ... |
|||
|
||||
GremlinProg |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ну, тут я уже просто предполагаю, что nns2009, организует какую-то сенсорику на залипании мыши, поэтому и предложил механизм захвата, конечно, если нужно только определяты выход за пределы клиентской/неклиентской области, то захват не нужен, как, впрочем, и таймер, поскольку этот механизм реализован в системе: TrackMouseEvent + WM_MOUSELEAVE/WM_NCMOUSELEAVE
Добавлено @ 14:15 хук, кстати, не слишком заумный, это крайний механизм перехвата всего и вся, здесь-то он зачем, когда можно обойтись более дипломатично, тем более, хук - узкое горлышко, ничего не стоит его просто перегрузить, в обоих смыслах )) Это сообщение отредактировал(а) GremlinProg - 10.2.2009, 14:16 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Это дело, к сожалению, звучит соблазнительно, но работает так себе. Во всяком случае, при тестировании мне довольно быстро удавалось получить ситуацию, когда MOUSELEAVE не приходил - просто быстро двигая мышкой. И я на этот способ забила. А таймер работает железно (ну, почти...) Впрочем, должна оговориться: дело было давно, уж не помню в каком виндоус. Возможно, сейчас этот способ работает стабильнее. Но осадок остался... ![]() -------------------- ... |
|||
|
||||
GremlinProg |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
да нет, нормально работает, о замечаниях к TrackMouseEvent я уже писал, правда давно, но, тем не менее, работает она до тех пор, пока очередь сообщений потока, владеющего окном, не пуста это ключевой момент ладно, добью таки до конца уже начатое, чтобы было понятно, когда необходимо дополнить любые сенсорные проверки на мышь кстати, это касается не только TrackMouseEvent, так же, любые проверки на WM_NCHITTEST или просто на WM_MOUSEMOVE, в общем - на любые проверки, которые производятся в ответ на оконные сообщения, зависимые от внешних устройств вот, к примеру, главный цикл окна:
что он делает? GetMessage - это "ядерная" функция, которая "спит" до тех пор, пока очередь пустая, т.е. этот вариант для TrackMouseEvent неудобен, поскольку нужное нам время GetMessage отдает другим процессам ок, теперь другой вариант:
PeekMessage - это более гибкий вариант GetMessage, который не отдает автоматом время другим процессам, вместо этого, она возвращает TRUE, если сообщение было успешно извлечено из очереди, и FALSE - когда извлекать из очереди просто нечего, она пустая при успешном возврате из PeekMessage, мы делаем то же самое, что и в примере выше, т.е. это обычная обработка сообщения, а вот в случае, когда PeekMessage возвращает FALSE, как раз и наступает время простоя(Idle), которое мы теперь можем использовать по своему есть 2 варианта 1. самим отдать время простоя в систему, т.е. дать возможность поработать другим задачам в этот период 2. сделать не слишком долгосрочную обработку чего-либо, пока сообщения в очереди вновь не появятся WaitMessage - первый вариант, эта функция будет просто "спать", пока очередь не активируется второй вариант - как раз то, что нам и нужно, т.е. мы сами можем здесь поставить необходимую нам обработку (допустим проверку текущих координат курсора на предмет присутствия его в нужной нам области и, в случае отсутствия - снять какие-либо флаги состояния, или напрямую вывести компонент в неактивный режим, вобщем, это уже непосредственно модель простоя, которую программист может реализовывать по своему вкусу и предубеждениям), после чего, если более время Idle нам не нужно, вызвать WaitMessage если не вызывать WaitMessage, или нагружать слишком много проверок в этот момент, то нагрузка на процессор будет 100% на протяжении всей работы приложения, так что не стоит этим злоупотреблять, поскольку обычная работа приложений уже будет нарушена + начнут вылезать различные артефакты, которым не было места при нормальной работе ну вот, теперь, похоже добил ) -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
GremlinProg, спасибо, интересная информация. Насчет того, что очередь сообщений не должна быть пуста, не знала. Я пыталась использовать TrackMouseEvent с MFC, а там свой цикл выборки сообщений (тоже PeekMessage + Idle-обработка).
Вмешаться, конечно, можно, но тогда я так далеко не влезала. -------------------- ... |
|||
|
||||
GremlinProg |
|
||||||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
ну, вобщем-то ничего нового я не открыл, на сколько я знаю, все средства разработки, будь то Delphi, MFC, WTL и т.п. - все предоставляют возможность обрабатывать время простоя, просто информации по поводу "как его использовать?" не слишком много. Большинство считают, что это аппендикс, который нужен только для расширения функционала программы
наверняка, каждый видел это магическое OnIdle с булевым параметром Done, так вот Done - как раз признак завершения времени простоя, который обычно упрощено раскрывается так:
OnIdle - тут либо глобальный метод, либо перебор всех окон потока с передачей флага в объектной модели методу OnIdle но вот здесь как раз и лежит подводный камень: флаг, сам по себе несет только признак, поэтому, если его передавать нескольким обработчикам (в цепочке простоя), реально, он может отражать только признак завершения для последнего, а не для всех. отсюда могут возникать неприятности при бузусловной установке флага (те самые промахи, при быстром движении мыши), поскольку
и
совершенно разные логические манипуляции в цепочке OnIdle, такого рода, нельзя использовать первый вариант, только второй - условная установка флага. Ситуацию можно легко поправить, если Done будет счетчиком Repeat:
и логически - понятно и соблазна поискать другой путь для решения, не возникает но я ни разу не встречал в onIdle явного счетчика, видимо из-за накладных расходов по документированию, благо, c WinAPI мы можем эти условности опустить и делать то, что нам действительно нужно. -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||||
|
|||||||||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |