Замораживание таймера при нажатии мышью на скроллбаре

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Замораживание таймера при нажатии мышью на скроллбаре

Сообщение Arkadia » 25.07.2008 (Пт) 19:48

Маленькая тестовая программка для демонстрации неприятного явления: в теле события таймера производятся действия. Если во время них начать тягать скроллбар - таймер больше не работает, пока мышь не отпущу. Но если схватиться за скроллбар в промежутке между срабатываниями таймера - он продолжает давать свои евенты.
Необходимо, чтобы таймер работал независимо от момента, когда юзер потянул ползунок - суть программы в том, что положение ползунка скроллбара уходит из компа наружу, а по этому таймеру парсятся и отображаются поступающие извне данные, которые являются функцией от положения ползунка и физической величины.
Попытки вставить в тело таймера Doevents и Sleep приводят только к тому, что последняя процедура не доводится до конца.
В реальной программе торможения ползунка не заметно, так как интервал таймера - 20мс. В примере я сделал 1 сек, чтобы выбирать, в активный или пассивный момент нажать мышью ползун скроллбара, и в результате отловить это неприятное явление.
Вложения
test.zip
тестовая программа
(1.32 Кб) Скачиваний: 124

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 25.07.2008 (Пт) 20:00

А разве это уже не было замечено? Мне кажится, что было уже. Особенно глюки появляются, когда Winsock вставляешь. Там такой намёк на многопоточность. В результате, когда отображаешь, скажем, Inputbox - ожидаешь, что всё остановится, пока юзер не введёт чего туда, но у меня уже ни раз случалось, что окошко Inputbox`a всё ещё не закрыто (никто ничего ещё не нажал), а прога дальше выполняется, до конца тела параллельной процедуры получения данных сокетом. Это конечно рационально всё, но всё же почему об этом нигде не предупреждали?
Follow the white rabbit.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 25.07.2008 (Пт) 20:11

Да мне не нужна многопоточность, даже вредна.
Но почему при нажатой неподвижной мыши таймер то застревает, то - нет? И аналогично - при перетягивании формы, а также при открытии меню - иногда таймер виснет, а иногда - щелкает, как положено.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 25.07.2008 (Пт) 20:27

Кстати, про меню. С меню другая задница, тоже страшно неприятная: при работе с ним или таймер останавливается (это плохо, но терпимо), или таймер продолжает молотить. Но меню при этом перестаёт давать свои евенты. Только разворачивается и замерзает.
Что делать?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 25.07.2008 (Пт) 21:54

Proxy
Ты пишешь полную чушь.

Arkadia
Что за глупость, делать в обработчике события таймера цикл, который создаёт задержку? Чем тебя не устраивает использовать для создания секундной задержки этот же самый таймер?

Что в переводе с твоего языка на русский означает "процедура не доводится до конца"?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 25.07.2008 (Пт) 23:50

Это не глупость - это же пример!
На самом деле там производится сложная обработка полученной информации (статистическое накопление, фильтрация, затухание). Затем - отображение в виде графика. Занимает десятки-сотни миллисекунд. Эти все дела делаются, конечно, не в событии таймера, а в процедурах, которые вызываются из события таймера когда пакет данных полностью засосан от внешнего девайса.
Сразу скажу - oncomm использовать нельзя - его нет у драйвера COM-USB, и, кроме того, oncomm стреляет повторно до конца обработки предыдущего пакета.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 25.07.2008 (Пт) 23:55

Процедура не доводится до конца - означает, что при нажатии на ползунок скролла в красный период индикатора:
с doevents/sleep - индикатор остаётся красным, и больше не мигает.
без doevents/sleep - индикатор становится зеленым, и больше не мигает.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 3:19

Это не глупость - это же пример!

Это пример глупости. Если у тебя не так, как в примере, то какой тогда смысл в этом примере?

Для присланного примера решение заключается в полном переделывании логики (по причине "Неправильное проектирование приложения").

Но если у тебя не так, а как-то иначе, то, не зная, как именно там у тебя, ответить что-либо конкретное нельзя.

Эти все дела делаются, конечно, не в событии таймера, а в процедурах, которые вызываются из события таймера

Разницы -- абсолютно никакой.

скажу - oncomm использовать нельзя - его нет у драйвера COM-USB,

Ничего не понял.

без doevents/sleep - индикатор становится зеленым, и больше не мигает.

Не правда.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 26.07.2008 (Сб) 8:04

Proxy
Ты пишешь полную чушь.

А мне кажится, было такое, когда запускаешь из самого vb, я точно помню. И ещё когда форму режешь (нестандартная форма окна) из среды бывает такое, что режется не то. После компиляции всё работает нормально. Сам видел.
Follow the white rabbit.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 8:17

В результате, когда отображаешь, скажем, Inputbox - ожидаешь, что всё остановится, пока юзер не введёт чего туда, но у меня уже ни раз случалось, что окошко Inputbox`a всё ещё не закрыто (никто ничего ещё не нажал), а прога дальше выполняется, до конца тела параллельной процедуры

Что такое параллельная процедура?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 26.07.2008 (Сб) 9:16

Ну я хз просто как иначе назвать. Вобщем иная. Вот.
Follow the white rabbit.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 10:00

Что значит иная? Какая иная? Иная, по отношению к чему?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 26.07.2008 (Сб) 10:24

Вобщем в одной вызывается Inputbox, а другая от сокета. И иногда случается так, что InputBox не стопорит всё, а позволяет выполнятся событию приёма данных сокетом.
Действие Inputbox`a похоже на

Do until <что-то было нажато>
...
loop

(Я не говорю, что так, просто говорю похоже на такую остановку)
А при применении Winsock при запуске из среды иногда входит как-будто

Do until <что-то было нажато>
DoEvents
...
loop
Follow the white rabbit.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 10:26

Proxy
А что по твоему делает DoEvents?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Сообщение SLIM » 26.07.2008 (Сб) 10:36

Я так понял Proxy имеет в виду что если посреди программы выходт InputBox программа не останавливается, она продолжает работать не ожидая возврата значения InputBox...
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 10:37

Тогда он не прав. InputBox модален.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Сообщение SLIM » 26.07.2008 (Сб) 11:20

Т.е. InpuBox дает СТОП программе?
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 11:22

Никаких стопов он не делает. Просто возврат из него обратно к вызывающему коду происходит только после того, как будет окно будет закрыто.

Точно также работает MsgBox. Точно также работает someform.Show с флагом vbModal.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Сообщение SLIM » 26.07.2008 (Сб) 11:38

Нет. Тогда такой вопрос, если есть цикл из 100 шагов. На 50-ом выходит InputBox. Будет ли цикл продолжаться или будет ожидать пока InputBox вернет значение? И соответственно если да, то как сделать обратное?
Пишите жизнь на чистовик.....переписать не удастся.....

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 26.07.2008 (Сб) 14:55

До меня только сейчас дошло. А ведь верно, что он таки и не останавливает всё подряд О_о
Хакер, спасиб, что объяснил.
Последний раз редактировалось Anonymous 26.07.2008 (Сб) 15:03, всего редактировалось 1 раз.
Follow the white rabbit.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 26.07.2008 (Сб) 15:01

Хакер писал(а):Это пример глупости. Если у тебя не так, как в примере, то какой тогда смысл в этом примере?

у меня не так, как в примере. Зачем оно Вам надо - разбираться в полуторамегабайтной exe? У меня вместо пустого цикла - циклы по массивам, в них обновляются данные по формулам от пришедшего массива. Масштабирования, затухания, интерполяции... Несмотря на оптимизацию, целочисленность и прочее - это занимает приличное время.

Хакер писал(а):Для присланного примера решение заключается в полном переделывании логики (по причине "Неправильное проектирование приложения").

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

Но если у тебя не так, а как-то иначе, то, не зная, как именно там у тебя, ответить что-либо конкретное нельзя.

я приложил пример. У меня - так. Я буду очень благодарен, если в этом примере таймер заработает как мне надо - это означает, что и в моей проге будет то же самое.

Ничего не понял.

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

Не правда.

у меня - так. Значит, еще глючокс.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 26.07.2008 (Сб) 23:40

У меня вместо пустого цикла - циклы по массивам, в них обновляются данные по формулам от пришедшего массива. Масштабирования, затухания, интерполяции... Несмотря на оптимизацию, целочисленность и прочее - это занимает приличное время.

Это самое. А может у тебя там оптимизация никудышная? Я не утверждаю, что именно так, но предполагаю, т.к. повидал очень много оптимизаторов, оптимизирующих в обратную сторону.


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

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

Так вот, известно ли тебе, что такое поток? Вот у тебя одновременно может выполняться тольк один код. Либо сейчас выполняется код, который делает математику, либо сейчас выполняется код, который обрабатывает перемещение ползунка.

Когда ты делаешь DoEvents, последняя проходится по очереди сообщений потока, и обрабатывает её. Оттуда (из Message-Loop-а) вызываются WindowProc-и, соотв. окон, и им скармливается информация о сообщении. Если вдруг СкроллБар получит сообщение, что его скроллят, его WindowProc (1) поставит на себя захват и (2) (предположительно) запускает внутри себя новый цикл по обработке сообщений. И этот цикл будет работать влоть до тех пор, пока таскать ползунок не закончат -- тогда захват снимется, и петля в WindowProc-е скроллбара закончится. Оттуда произойдёт возврат в DoEvents. А из DoEvents-а произойдёт возврат к твоему коду.

Либо ты не делаешь DoEvents, и тогда пока идут расчёты, не выполяется никаких wm-related событий, т.е. ничего не отрисовывается и никто не реагирует на нажатия клавы/мышки.

Либо ты делаешь DoEvents, но тогда, если скролбар начинут скроллить, возврат из DoEvents задержится до тех пор, пока скроллбар не начнут скроллить.

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

Можено попробовать сделать умно, применив фиберы. Можно попробовать сделать глупо, сделав счедуллинг на базе таймера.

у меня - так. Значит, еще глючокс.

Ага. Кучи людей здесь плакало о том, что пока у них работает длинный цикл, внутри которого нет DoEvents, у них не реагирует GUI. А тебя, значит, наоброт, такой полезный глючок, что пока работает длинный цикл, GUI продолжает работать.

И ты не понимаешь, что это невозможно без существования отдельного обработчика, который бы обрабатывал очередь сообщений потока. Где-же он, этот обработчик, как он работает, если в потоке одновременно выполняется только один код, а в другом потоке этого обработчика быть не может, потому что у др. потока будет своя очередь?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 27.07.2008 (Вс) 16:37

Хакер писал(а):Это самое. А может у тебя там оптимизация никудышная? Я не утверждаю, что именно так, но предполагаю, т.к. повидал очень много оптимизаторов, оптимизирующих в обратную сторону.


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


Либо сейчас выполняется код, который делает математику, либо сейчас выполняется код, который обрабатывает перемещение ползунка.

Вы не поняли: я не таскаю скролл-бар, я его просто нажимаю мышью. И это блокирует работу таймера, если нажал во время его срабатывания. И не блокирует, если нажал в интервалах.

К событию scroll у меня претензий нет - оно работает, и по нему в девайс уходят настройки (это почти мгновенно). Но вот принятие от девайса информации - замораживается пока пользователь держит скролл. А пользователь не должен отпускать скролл, пока не увидит результат перемещения скролла! Но увидеть он не может - нажатый скролл иногда (!!!) блокирует прием от девайса.

Либо ты не делаешь DoEvents, и тогда пока идут расчёты, не выполяется никаких wm-related событий

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

Ага. Кучи людей здесь плакало о том, что пока у них работает длинный цикл, внутри которого нет DoEvents, у них не реагирует GUI. А тебя, значит, наоброт, такой полезный глючок, что пока работает длинный цикл, GUI продолжает работать.


не GUI продолжает работать, а этот длинный цикл продолжает работать:
если в нем нет doevents - он способен закончиться, если в его ходе нажали ползунок. А если в длинном цикле есть doevents - то нажатие мышью ползунка скролла уже не дает этому циклу закончиться. И в обоих случаях таймер уже не дает новых событий. Кстати, я понял - почему! У меня в самом конце, чтобы показать зелененькое - стоит doevents. И вот из-за него таймер мерзнет.

Я убрал из цикла DoEvents. И всё заработало, как мне надо. То есть:
нажатие бегунка скролла
нажатие на заголовке окна
вход в меню
- это всё больше не останавливает таймер!

Прикладываю демонстрационный проект - по частоте мигания он ближе к реальному. Мигает часто, поэтому точно попасть на красное/зеленое не получится. Но соотношение попал-не попал то же самое - 50на50. В варианте с "doevents" мигание в 50% случаев прекратится: при перетягивании формы, при скролле, при работе с меню. В варианте без "doevents" - таймер работает как обязан!
Вложения
test2.zip
(1.56 Кб) Скачиваний: 114

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 27.07.2008 (Вс) 16:52

Вы не поняли: я не таскаю скролл-бар, я его просто нажимаю мышью. И это блокирует работу таймера, если нажал во время его срабатывания. И не блокирует, если нажал в интервалах.


Да это не блокирует работу таймера. Это откладывает возврат из DoEvents в обработчик события Timer.

Если же ты нажимаешь вне времени срабатывания, то откладывается возврат в стандартный VB-шный MessageLoop. Но новый MessageLoop, который работает в WindowProc-е скроллбара диспатчит WM_TIMER-сообщения: поэтому у тебя складывается такое впечатление, что ничего не стопорится.

На самом же деле, тыбе бы сейчас "помог" "неждущий таймер", о котором так мечтал arthur2. Однако помог бы он тебе только визуально: всё бы выглядело хорошо, а на деле появилась бы бесконечно растущая рекурсия.

Блин, автор, нучись цитировать текст! :twisted:

я их делаю - но они не помогают.

И не должны помогать. Ты их делаешь только потому, что тебе, вероятно, нравится название этой функции. А её истинной сути ты не понимаешь.

после них таймер замерзший?

Потому что не произошёл вовзрат из предыдущего callframe'а обработчика события таймера.

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

Это ты в силу своей необразованности наивно полагаешь, что никакой код не выполняется. На самом же деле, как только ты зажимаешь мышку на ползунке скролла, начинает выполняться цикл внутри WindowProc-а скроллбара. И этот цикл не закончит выполняться, пока ты не отпустишь ползунок. А пока этот цикл не закончит выполняться, выполнение не вернётся в DoEvents. А пока оно не вернётся в DoEvents, оно уж точно не вернётся в Timer1_Timer. А пока оно не вернётся в Timer1_Timer, оно не вернётся в базовый MessageLoop. А пока оно не вернётся в базовый MessageLoop, таймер будет, как ты говоришь "заморожен".

если в нем нет doevents - он способен закончиться, если в его ходе нажали ползунок.

В его ходе не зажмут ползунок: некому будет обработать зажатие.

Прикладываю демонстрационный проект

Мне не нужно демонстрационные проекты, потому что я и без них представляю, какая ситуация у тебя сложилась. И я тебе объясняю, почему она сложилась, и почему выйти из неё так, как тебе хотелось бы, невозможно. Но ты упорно пытаешься непонимать меня.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 27.07.2008 (Вс) 17:25

Хакер писал(а):В его ходе не зажмут ползунок: некому будет обработать зажатие.

вот это мне и надо! Действие, выполняемое по таймеру, имеет у меня наивысший приоритет. А таскание формы по столу и мышиная возня - могут и затормозиться на 50-200 миллисекунд, если они такие серьезные, что (ничего по сути не делая) отнимают у таймера возможность сработать.
Спасибо за помощь, и особо - за вежливость!

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 27.07.2008 (Вс) 17:40

как только ты зажимаешь мышку на ползунке скролла, начинает выполняться цикл внутри WindowProc-а скроллбара. И этот цикл не закончит выполняться, пока ты не отпустишь ползунок.

нет, всё-таки не удержусь, и прокомментирую это. В начале ветки Вы сказали, что так программы не пишут.
Так вот: мышь - это такая пластмассовая коробочка, внутри которой микросхема. И эта микросхема посылает компу события и нажатия, и отпускания кнопки. Поэтому писать программу так, чтобы она крутилась непрерывно в цикле, ожидая отпускания кнопки, когда есть отдельные события - это и есть, как Вы написали, "что за глупость". Да, я не специалист по потрохам Виндовса, я реалтаймовик - ассемблерщик. И я не ожидал такой глупости.
Кстати, а почему нажатие клавиши на клавиатуре не заводит бейсик в бесконечный цикл? Вот было бы здорово! Вставил doevents, чтобы отловить кнопку - а оно взяло, и завесило то, что должно затем среагировать на эту кнопку!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 27.07.2008 (Вс) 21:34

вот это мне и надо!

А так и есть. Если делать цикл, и не делать в нём DoEvents, то так и будет. Если так не есть, значит откуда-то всё-таки этот DoEvents вызывается.

Действие, выполняемое по таймеру, имеет у меня наивысший приоритет. А таскание формы по столу и мышиная возня - могут и затормозиться на 50-200 миллисекунд, если они такие серьезные, что (ничего по сути не делая) отнимают у таймера возможность сработать.

О приоритетах можно говорить, когда какие-то две задачи выполняются одновременно. Параллельно. Или псевдопараллельно. Когда речь идёт о потоках, например. У тебя же один поток, который выполняется линейно. И выполнение в нём какого-либо места зависит исключительно от одного фактора: кто-то должен передать выполнение в это место.

У тебя (ты ещё не понял что-ли) выполнение переходит в DoEvents и не передаётся обратно пока не закончат работать с ползунком.

Никакими приоритетами, шаманствами и прочими делами нельзя изменить эту ситуацию -- это естественное поведение.


нет, всё-таки не удержусь, и прокомментирую это.

Я тоже.

В начале ветки Вы сказали, что так программы не пишут.

Да. У VB, на котором ты пишешь, Event-Driveт-парадигма. Ты ею в полной мере не пользуешься, а пользуешься во-первых, так, что теряются её преимущества, а во-вторых, вобщем-то -- неправильно пользуешься.

И эта микросхема посылает компу события и нажатия, и отпускания кнопки.

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

Поэтому писать программу так, чтобы она крутилась непрерывно в цикле, ожидая отпускания кнопки, когда есть отдельные события - это и есть, как Вы написали, "что за глупость"


Вообще-то так работает Windows и все приложения под эту ОС. Чтобы обработчик какого-то события смог его отбработать, надо чтобы кто-то запустил этот обработчик. А кто, скажи мне, кто может это сделать, кроме как цикл из того же потока?

Кстати, а почему нажатие клавиши на клавиатуре не заводит бейсик в бесконечный цикл? Вот было бы здорово! Вставил doevents, чтобы отловить кнопку - а оно взяло, и завесило то, что должно затем среагировать на эту кнопку!

Нажатие клавиш практически никто не обрабатывает. Ты, если считаешь что "было бы здорово!" можешь сделать такое, установив обработчик для KeyPress/KeyDown событий и сделав там бесконечный цикл.

Почему зажатие ползунка приводит к возникновению бесконечного цикла в его WP -- спроси у тех, кто писал скроллбары. Вероятно, они просто не нашли другого способа некриво реализовать перетаскивание.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 28.07.2008 (Пн) 1:49

Хакер писал(а): У тебя (ты ещё не понял что-ли) выполнение переходит в DoEvents и не передаётся обратно пока не закончат работать с ползунком.

это я уже понял. Уберу doevents.
Чтобы обработчик какого-то события смог его обработать, надо чтобы кто-то запустил этот обработчик. А кто, скажи мне, кто может это сделать, кроме как цикл из того же потока?

прерывание. Ну или опрос по таймеру.
Ведь не всё останавливается: если один таймер завис, то другой таймер на этой же форме продолжает работать.
Почему зажатие ползунка приводит к возникновению бесконечного цикла в его WP -- спроси у тех, кто писал скроллбары. Вероятно, они просто не нашли другого способа некриво реализовать перетаскивание.

да не только в сколлбаре дело. За заголовок формы если схватиться - тоже таймер застрянет, если это произошло в событии таймера, в котором есть doevents.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 28.07.2008 (Пн) 2:35

прерывание.

Прерывания ушли в небытие. Нет прерываний. Единственное прерывание, которое работает как прерывание, но до которого тебе далеко не добраться -- прерывание, осуществляющее переключение между задачами процессора. Задачами процессора в нашем случае являются потоки.

Ну или опрос по таймеру.

Что в данном случае принимать за таймер? Код, который будет делать опрос -- кто его, опять же, будет вызывать?

Ведь не всё останавливается: если один таймер завис, то другой таймер на этой же форме продолжает работать.

Ерунда. Если один таймер (т.е. внутри Timer1_Timer'а работает бесконечный цикл), то ничего кроме этого цикла в рамках потока вообще не работает.

да не только в сколлбаре дело. За заголовок формы если схватиться - тоже таймер застрянет, если это произошло в событии таймера, в котором есть doevents.

Да, и что? И наверное сыщется ещё с десяток контроллов, которые делают подобный трюк, завладевая обработкой очереди сообщений.

Таймер здесь тоже абсолютно не причём. Просто таймер единственный, пожалуй, достыпный тебе способ наблюдать данный эффект.

По сути, у тебя происходит примерно следующее:
(Примечание: КРБ - Контррекурсионная блокировка. Если бы её небыло, у тебя таймер бы продолжал тикать, пока таскают скроллбара, но от этог получилась бы рекурсия; в итоге, у тебя за секунду сожрался бы весь стек и процесс умер от его нехватки)
Изображение
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Сообщение Proxy » 28.07.2008 (Пн) 7:38

Немножко оффтоп, но важно мне:
Хакер, чем рисуешь? Это же не фотошоп, судя по выноскам?
Follow the white rabbit.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 54

    TopList