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

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

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

1) Такое имеет место быть, когда ты в таймере вызываешь DoEvents и в это время начинают делать скроллинг. Сам же ты говоришь о голом таймере. Почему ты взял и спокойно перенёс это на голые таймеры?

Я смогу её завершить - если в ней стоит проверка флага, а флаг установить таймером.

А это надо сразу на башорг. Давай, продемонстрируй общественности код, который надо поместить в B, чтобы разрушить стековый фрейм A, но при том, на выходить из B. (обязательно собладать условие "не выходя из B")
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 30.07.2008 (Ср) 20:49

(обязательно собладать условие "не выходя из B")
Не передёргивай - естественно, с выходом из В.

А продемонстрировать... так я же уже запостил свой маразматический код. Ты его посмотрел, или опять споришь неглядя?
Артур
 
   

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

Сообщение Хакер » 30.07.2008 (Ср) 20:53

Не передёргивай - естественно, с выходом из В.

Ты адекватен? С выходом из B никакого флага нафиг не нужно, всё само собой завершится. Что ты нам хотел продемонстрировать?

Только вот у тебя не будет выхода из B. У тебё из B вызовется C, из C — D, а из D — E и так далее, пока не кончится стек.

Назвать причину, по которой этого не произойдёт ты не сможешь. А чтобы этого не произошло — надо не вызывать DoEvents или реализовывать КРБ.

Не вызывая DoEvents не будет работать скролл, с реализацией КРБ всё будет в точности как сейчас с VB-шным таймером.

Ты его посмотрел, или опять споришь неглядя?

Спорю не глядя. Зачем мне читать страничное доказательство того, что 0 * 0 будет 777, когда я знаю и все знают, что будет 0? Я могу продолжать спорить, даже не читая этого доказательства, заведомо зная, что оно бредовое.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 30.07.2008 (Ср) 21:01

Спорю не глядя. Зачем мне читать страничное доказательство того, что 0 * 0 будет 777, когда я знаю и все знают, что будет 0? Я могу продолжать спорить, даже не читая этого доказательства, заведомо зная, что оно бредовое
Действительно, зачем спорить с человеком, которого считаешь тупицей?

Ещё раз: код работает. Скрол крутится. Вычисления (ну или мигания) не замирают. Стек не переполняется. Рекурсия НЕ ВОЗНИКАЕТ!!! Защита от рекурсии там есть. Возможно, код маразматический. Но в чём его маразматичность - ты смотреть не стал.

Действительно, зачем? - давай лучше поговорим о моей адекватности.
Артур
 
   

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

Сообщение Хакер » 30.07.2008 (Ср) 21:02

arthur2
А скажи мне, как ты проверяешь, возникает ли рекурсия?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 30.07.2008 (Ср) 21:23

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

В моём коде рекурсия возникает только в одно вложение. Как и было задумано.

Код не привожу - ты же всё равное читать не станешь. Или привести?
Артур
 
   

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

Сообщение Хакер » 30.07.2008 (Ср) 21:25

arthur2
Хорошо, допустим, благодяря КРБ у тебя рекурсия ограничена в один уровень вложенности.

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

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 30.07.2008 (Ср) 21:48

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

После чего цикл вычислений прерывается - и возобновляется уже в новом тике (точнее, через тик - потому что в каждом втором тике вместо цикла стоит выставление флага).

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


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

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

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

Сообщение Хакер » 31.07.2008 (Чт) 8:44

У меня крб есть, но реализована наоборот - прерывается не новый тик, а старый.

Та сам то хоть понимаешь всю степени маразма, содержащегося в этой фразе?

КРБ это Контр-Рекурсионная Блокировка. Это значит, что она работает против разнастания стека вверх, а не для убийтсва подлежащих фреймов.

Нельзя завершить предыдущий тик из нового. Если этот вызван не из предыдущего — предыдущего просто не существует. А если из предыдущего, то никто не сможет проверить твой флаг, пока выполнение не вернёлся в предыдущий? А зачем тогда городить какие-то блокировки, если по возврату в предыдущий фрейм он и так сам по себе закончится?

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


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

Не, вот, а....

Единственной процедурой, которая замирает (зависает) была оконная процедура ScrollBar-а. Ты в ней что-ли, родной, хочешь проверку вставить? Мало того, что ты не сможешь, если бы ты смог, ты бы поламал скроллинг.

Или тебе видится ещё какая-то процедура, которая замирает? Расскажи мне о ней. Потому что таких процедур нет — единсветнное, что замирало, так это ML внутри SBWP, до тех пор пока не произойдёт отпускание мыши.

Единственное пожалуй, что тебе действительно под силу сделать — это в качестве установки своего флага надуть скроллбар — послать ему WM_LBUTTONUP заставив проверить, что таскать ползунок прекратили. Вот тогд замерший SBWP действительно прекратит лупиться, и отдаст управление обратно в DoEvents, а потом и в обработчик первого тика.

Но это поломает скроллбара. Но это поломает скроллбар — его познунок будет в лучшем случае через пиксель drop-аться после того, как он начал drag-аться.

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

Ну да, принцип FCLR у тебя на процедуры не распространяется. Я вот подумал, а не зря ли я трачу время, вдалбливая, что этот принцип есть?
—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 » 31.07.2008 (Чт) 13:55

Замирает не скроллбар, замирает таймер.
Замирание происходит не от таскания ползунка. И не от нажатой на нем кнопки мыши. А от нажатия! То есть не от состояния, а от события. Если кнопка мыши нажата на скроллбаре в интервале таймера (а не внутри эвента timer) - то хоть жми на скроллбар, хоть таскай его - никакого вреда.

Еще замирает таймер при таскании формы по столу.
А вот меню - меню от таймера повисает, то есть перестает реагировать на мышь: если вошел в меню в активное время таймера, то оно разворачивает свою иерархию, но выбрать пункт не дает: остается открытым, евент click не генерит.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 31.07.2008 (Чт) 14:27

Arkadia, интересный у тебя, однако, таймер. Останавливается там, где не надо, меню замороживает, когда не надо.
Весь мир матрица, а мы в нем потоки байтов!

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 31.07.2008 (Чт) 22:00

Arkadia
Это понятно. Но апи-таймер - не замирает. Если конечно его специально не заморозить. Так что и проблемы такой не будет (будет другая - наложение нескольких тиков друг на друга, об чём мы тут с Хакером и ломаем копья о мою голову)

Хакер
Это значит, что она работает против разнастания стека вверх, а не для убийтсва подлежащих фреймов.

Я не знал, что это строго оговореный термен. Хорошо, то, что у меня - это не крб, а просто защита от нарастания рекурсии.

А зачем тогда городить какие-то блокировки, если по возврату в предыдущий фрейм он и так сам по себе закончится?
Не закончится - там в цикле единственный выход - по флагу.

Код, про который мы говорим, в десять строк, но прочитать его - это же унизиться перед таким тупицей, как я. Хорошо, код маразматический - даже спорить с этим не буду. Но он работает именно так, как я и предпологал. Работает. Маразматически, но работает. Рекурсия не возникает, цикл по флагу прерывается. А ты говорил, что работать не будет. Скажы, что именно в маразматическом коде - вытаскивание себя за волосы? В каком месте мне удалось-таки преодалеть законы физики и твои предсказания?

А вообще - лучше не говори. Мне не очень охота беседовать в таком тоне. Удачи на дорогах.
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 31.07.2008 (Чт) 22:14

Нельзя завершить предыдущий тик из нового

Зато можно из предыдущего тика узнать, что уже наступил следующий. Или тоже нельзя?
Артур
 
   

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.08.2008 (Пт) 7:36

arthur2 писал(а):Зато можно из предыдущего тика узнать, что уже наступил следующий. Или тоже нельзя?

Ты не уловил суть.
Если у тебя в предыдущем коде есть такой фрагмент:
Код: Выделить всё
Do ...
  ...
  If fExit Then Exit Sub
Loop

то он не сработает, пока весь цикл не выполнится (и процедура не завершится самостоятельно). И неважно, API-таймер это или VB.
Если же перед If fExit ты добавишь DoEvents, то в If fExit управление попадет только после того, как отработает весь код, вызванный в DoEvents. То есть цикл оконных сообщений, обработчик TimerProc, твоя процедура (рекурсивно вызванная), в которой взводится флаг и выполняется Exit Sub. Однако из своей процедуры ты выйдешь не в предыдущую процедуру, а в TimerProc, а когда тот вернет управление в предыдущую процедуру, ты не знаешь.
Lasciate ogni speranza, voi ch'entrate.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 8:51

alibekДа, перед выходом есть дуевентс.

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

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

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

Я не пытаюсь доказать, что я один тут прав, а все остальные неправы, я просто хочу разобраться. Куда именно возвращает управление timeproc? И как вызывается следующий? В чём вообще ошибка моей логики?
Артур
 
   

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

Сообщение Хакер » 01.08.2008 (Пт) 8:59

arthur2

Ведь следующий тик вызывается системой не не рекурсивно из предыдущего?


Чёрт возьми, следующий тик вызывается из ML внутри SBWP, который вызван из ML внутри DoEvents, которая вызывается из предыдущего тика.

Я тебе уже сказал считать, что следующий тик вызывается из предыдущего.

Флаг я возвожу вовсе не из рекурсивно вызваной процедуры, а из следующего тика.

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

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 9:08

Хакер
А если timeproc вообще без кода - он откуда вызывается? тоже из предыдущего? Они что, по-разному вызываются? (я не иронизирую, а спрашиваю)

Из того, что ты говоришь, я понимаю отсилы четверть. Может тебе кажется, что ты уже всё разжевал и в рот положил, но я по-прежнему не понимаю, в чём ошибка моей логики. И главное - код ведь работает, и стек не переполняется, почему же тогда его нельзя использовать?
Артур
 
   

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

Сообщение Хакер » 01.08.2008 (Пт) 9:12

Что такое timeproc? timerproc с кодом, этот код возвится с IConnectionPoint-ами своего контрола-таймера.

Вызывается он из ML.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.08.2008 (Пт) 9:13

arthur2 писал(а):А если timeproc вообще без кода - он откуда вызывается? тоже из предыдущего?

Что без кода? Обработчик VB-шного события таймера Timer? Оконный TimerProc?
Lasciate ogni speranza, voi ch'entrate.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 9:18

alibek
Безаконный timeproc в модуле.
Артур
 
   

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

Сообщение Хакер » 01.08.2008 (Пт) 9:20

Я писал(а):Вызывается он из ML.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.08.2008 (Пт) 9:22

Он не может быть без кода. Как минимум, там будет Sub и End Sub.
Lasciate ogni speranza, voi ch'entrate.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 9:25

alibek
И откуда он вызывается?
Артур
 
   

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

Сообщение Хакер » 01.08.2008 (Пт) 9:26

Хакер писал(а):
Я писал(а):Вызывается он из ML.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 9:28

alibek
Код: Выделить всё
Private Sub TimerProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal lngSysTime As Long)
   cntIn = cntIn + 1
   Debug.Print "вход " & cntIn
    flExit = Not flExit
     
    If Not flExit Then
         Do
           DoEvents
           If flExit Then
               flExit = False
               cntOut = cntOut + 1
               Debug.Print "выход " & cntOut
               Exit Sub
           End If
           Call DoSomething
         Loop
    End If

End Sub

В чём здесь ошибка?
Последний раз редактировалось arthur2 01.08.2008 (Пт) 9:39, всего редактировалось 1 раз.
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 9:33

Хакер
Круто. А что такое МЛ? И главное - этот МЛ из предыдущего-таки тика, или откуда-то из другого места?
Артур
 
   

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

Сообщение Хакер » 01.08.2008 (Пт) 9:34

А здесь нет кодовой ошибки. Здесь логическая ошибка.

Этот бредовый код работает так:

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

История повторяется...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Хакер » 01.08.2008 (Пт) 9:35

arthur2
ML это MessageLoop. Изучай картинку...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 01.08.2008 (Пт) 9:42

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

Мы обсуждаем не бредовость, а работоспособность (пусть и бредового) кода.
Артур
 
   

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

Сообщение Хакер » 01.08.2008 (Пт) 9:45

arthur2
Логическая ошибка не в коде, а в твоей голове, в твёом понимание, в твоём предположении того, что этот код будет стабильно себя вести если его поместить в реальные условия (которые были у автора).

У этого кода возникнет некотролируемая рекурсия при таскании скроллбара.

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

Пред.След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

    TopList