Не работает элементарный таймер

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

Не работает элементарный таймер

Сообщение BazaroffAM » 07.06.2013 (Пт) 18:39

Постигаю учебник. Юзаю VB6.
При запуске формы таймер отображает текущее время (на момент запуска формы). А отсчет времени не идет.
Код до единого символа скопирован из учебника:

Код: Выделить всё
Private Sub Form_Load()
Label1.Caption = Second(Time)
Label2.Caption = Minute(Time)
Label3.Caption = Hour(Time)
Timer1.Enabled = True
End Sub


При чем, сначала код был представлен без строки

Код: Выделить всё
Timer1.Enabled = True


и автор подчеркивает, что идти этот таймер не будет, а будет лишь отображаться текущее время на момент запуска формы. И было так!
Далее автор указывает на необходимость вставить в код эту строку для того, чтобы таймер "пошел". Ан нет!
В чем ошибка?

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 07.06.2013 (Пт) 19:58

BazaroffAM писал(а):В чем ошибка?

А где обработчик Timer1_Tick?

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

Re: Не работает элементарный таймер

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

Qwertiy писал(а):А где обработчик Timer1_Tick?

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

BazaroffAM
Новичок
Новичок
 
Сообщения: 46
Зарегистрирован: 31.05.2013 (Пт) 19:18

Re: Не работает элементарный таймер

Сообщение BazaroffAM » 08.06.2013 (Сб) 11:12

Да уж... Как ни странно в библии этого нет. :?

Не смог найти подходящего примера кода с этим обработчиком. А может и попадался, да я просто не знаю что нужно заимствовать.
Помогите плиз с кодом и местом куда этот код запихнуть. :)

BazaroffAM
Новичок
Новичок
 
Сообщения: 46
Зарегистрирован: 31.05.2013 (Пт) 19:18

Re: Не работает элементарный таймер

Сообщение BazaroffAM » 08.06.2013 (Сб) 12:23

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

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Не работает элементарный таймер

Сообщение iGrok » 08.06.2013 (Сб) 14:09

BazaroffAM писал(а):Как я понимаю эта строка служит для запуска таймера как такового.

Именно.
label:
cli
jmp label

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 08.06.2013 (Сб) 16:38

BazaroffAM писал(а):Не смог найти подходящего примера кода с этим обработчиком.

Как поправил Хакер, должна быть процедура Timer1_Timer, содержащая те 3 строчки с занесением времени в лейблы.
Кстати, вызывать трижды Time плохо, т. к. значение может измениться.
И вообще, можно сделать 1 Label и помещать в него отформатированную строку.

aleksmir
Обычный пользователь
Обычный пользователь
 
Сообщения: 88
Зарегистрирован: 10.08.2009 (Пн) 13:17

Re: Не работает элементарный таймер

Сообщение aleksmir » 13.06.2013 (Чт) 5:25

Код: Выделить всё
Private Sub Form_Load()
Label1.Caption = Second(Time)
Label2.Caption = Minute(Time)
Label3.Caption = Hour(Time)
Timer1.Interval=1000
Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
Timer1.Enabled=False
Label1.Caption = Second(Time)
Label2.Caption = Minute(Time)
Label3.Caption = Hour(Time)
Me.Refresh
Timer1.Enabled=True
End Sub


Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 13.06.2013 (Чт) 6:54

Зачем выключение и включение таймера? И Refresh тоже?

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

Re: Не работает элементарный таймер

Сообщение alibek » 13.06.2013 (Чт) 8:25

aleksmir, глупо без причины одинаковый код использовать в нескольких местах.
В Form_Load нужно только включить таймер. А чтобы не было секундного лага, нужно не повторять код, а просто вызвать Timer1_Timer.
Lasciate ogni speranza, voi ch'entrate.

aleksmir
Обычный пользователь
Обычный пользователь
 
Сообщения: 88
Зарегистрирован: 10.08.2009 (Пн) 13:17

Re:

Сообщение aleksmir » 13.06.2013 (Чт) 9:43

Qwertiy писал(а):Зачем выключение и включение таймера? И Refresh тоже?

Ну Refresh можно не делать в данном примере. Я привел общий случай. На практике встречал, когда текст не прорисовывается и всегда на всякий случай ставлю Refresh вместе с DoEvents.
Включение и выключение таймера тоже общий случай. При сложной процедуре обработке события (когда время обработки превысит интервал таймера) может возникнуть следующее срабатываение таймера раньше, чем закончится обработка предыдущего срабатывания. Лучше заранее 10 раз перестраховаться, чем потом отлавливать глюки программы. Я так считаю)

alibek писал(а):aleksmir, глупо без причины одинаковый код использовать в нескольких местах. В Form_Load нужно только включить таймер. А чтобы не было секундного лага, нужно не повторять код, а просто вызвать Timer1_Timer.


Можно я не спорю) Оптимизировать код - это уже забота автора проекта. Я просто добавил работающий пример обработки события таймера, не трогая его предыдущий код в Form_Load.

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

Re: Re:

Сообщение alibek » 13.06.2013 (Чт) 10:07

aleksmir писал(а):При сложной процедуре обработке события (когда время обработки превысит интервал таймера) может возникнуть следующее срабатываение таймера раньше, чем закончится обработка предыдущего срабатывания. Лучше заранее 10 раз перестраховаться, чем потом отлавливать глюки программы. Я так считаю)

Неверно. Программы на VB однопоточные. И событие таймера не возникнет, пока выполняется обработка предыдущего события (или пока не будет вызван DoEvents).
Lasciate ogni speranza, voi ch'entrate.

aleksmir
Обычный пользователь
Обычный пользователь
 
Сообщения: 88
Зарегистрирован: 10.08.2009 (Пн) 13:17

Re: Re:

Сообщение aleksmir » 13.06.2013 (Чт) 10:25

alibek писал(а):Неверно. Программы на VB однопоточные. И событие таймера не возникнет, пока выполняется обработка предыдущего события (или пока не будет вызван DoEvents).

Возможно. Спорить не буду. На таких мелочах не заморачиваюсь.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 13.06.2013 (Чт) 10:33

aleksmir писал(а):Лучше заранее 10 раз перестраховаться, чем потом отлавливать глюки программы. Я так считаю)

А на мой взгляд, надо думать, а не перестраховываться... Тем более, такое обращение с таймером фактически увеличивает интервал между вызовами, поскольку будет не 1 секунда, а 1 секунда плюс время выполнения кода.
И вообще, в этом коде всё равно баг, т. к. время может измениться между обращениями к Time и будет показано совсем неверное (с ошибкой в 1 час, в худшем случае) :D

aleksmir
Обычный пользователь
Обычный пользователь
 
Сообщения: 88
Зарегистрирован: 10.08.2009 (Пн) 13:17

Re:

Сообщение aleksmir » 13.06.2013 (Чт) 10:48

Qwertiy писал(а):А на мой взгляд, надо думать, а не перестраховываться...

С нашим ритмом жизни время на "подумать" бывает очень редко) Поэтому появляется избыточный и неоптимизированный код. Часто бывает, что "не до мелочей".

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Не работает элементарный таймер

Сообщение iGrok » 13.06.2013 (Чт) 11:07

aleksmir писал(а):С нашим ритмом жизни время на "подумать" бывает очень редко)

Этак можно далеко зайти. Такой ритм жизни нужно однозначно менять...
label:
cli
jmp label

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

Re:

Сообщение alibek » 13.06.2013 (Чт) 11:36

Qwertiy писал(а):Тем более, такое обращение с таймером фактически увеличивает интервал между вызовами, поскольку будет не 1 секунда, а 1 секунда плюс время выполнения кода.

Не увеличивает. Таймер «тикает» не с мгновения запуска, а кратно системному таймеру.
Lasciate ogni speranza, voi ch'entrate.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 13.06.2013 (Чт) 11:42

alibek писал(а):Не увеличивает. Таймер «тикает» не с мгновения запуска, а кратно системному таймеру.

В смысле? И что значит кратно? Системный таймер ведь наверняка не раз в секунду тикает :)

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

Re: Не работает элементарный таймер

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

aleksmir писал(а):Возможно. Спорить не буду. На таких мелочах не заморачиваюсь.

Не «возможно», а точно. Это не мелочь, а фундамент, без четкого понимания которого невозможно писать программы с правильной логикой.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 13.06.2013 (Чт) 12:52

Неужели никто не прочитает лекцию о работе таймера? Интересно ведь стало ;)

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

Re: Не работает элементарный таймер

Сообщение Хакер » 13.06.2013 (Чт) 12:59

Qwertiy писал(а):Неужели никто не прочитает лекцию о работе таймера? Интересно ведь стало ;)

Я бы прочитал, но жутко некогда. Пока всё надежда на вас :) Потом исправлю неточности, если что
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.06.2013 (Пт) 8:20

alibek, расскажи про таймер-то ;)

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

Re: Не работает элементарный таймер

Сообщение alibek » 14.06.2013 (Пт) 8:37

А что рассказывать то?
Крутится ML, который на сообщения WM_TIMER вызывает события соответствующих подписчиков.
Нужно только понимать, что вызываются они не волшебным образом, а регламентированным, в MSDN все подробно описано.
При получении оконного сообщения вызывается соответствующее событие для графических элементов управления. Обработчик этого события — это процедура на VB и управление возвращается в ML только после того, как эта процедура завершит работу (дойдет до End Sub или Exit Sub). Если в процессе выполнения процедуры в ML пришло еще одно оконное сообщение, то текущая процедура не прерывается, а продолжает работать, а оконное сообщение поступает в очередь и будет обработано на следующем проходе ML. В процедуре можно вызвать DoEvents, что инициирует обработку оконных сообщений (в очереди), но это не распараллеливание, а вызов (т.е. после обработки сообщения управление вернется в процедуру, а из нее в основной ML) и если делать это бездумно, то может возникнуть рекурсия и переполнения стека.
Lasciate ogni speranza, voi ch'entrate.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 14.06.2013 (Пт) 8:52

Это-то понятно. А вот почему выключение и повторное включение таймера не изменяет интервал, там что-то не видно. А меня как раз эта часть заинтересовала.

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

Re: Не работает элементарный таймер

Сообщение alibek » 14.06.2013 (Пт) 9:08

Потому что включение и выключение таймера включает или выключает подписку на событие WM_TIMER, а не управляет таймером.
Само же событие инициируется системным таймером.
Lasciate ogni speranza, voi ch'entrate.

drronnie
Постоялец
Постоялец
 
Сообщения: 793
Зарегистрирован: 04.03.2002 (Пн) 22:29
Откуда: Украина, Алчевск

Re: Не работает элементарный таймер

Сообщение drronnie » 14.06.2013 (Пт) 12:04

Пардон за офтоп. Случайно зашёл в конфу понастальгировать. Не думал, что кто-то еще пишет на родном vb6:)
И родные лица те же: alibek да Хакер:)
Всем удачного дня.
Компиляция - перевод словесного поноса в машинный код.

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

Re: Не работает элементарный таймер

Сообщение Хакер » 14.06.2013 (Пт) 18:53

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

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

Re: Не работает элементарный таймер

Сообщение Хакер » 14.06.2013 (Пт) 19:11

И самое главное: интервал таймера — это именно интервал таймера, а не период срабатывания.
Он отсчитывается от конца работы обработчика события, а не от момента предыдущего срабатывания.

То есть на картинке левая часть показывает суть вещей неправильно, а правая, соответственно, правильно:
vb6_timer_nature.png
vb6_timer_nature.png (18.83 Кб) Просмотров: 14281


Здесь, для примера: интервал таймер = 10 секунд, а время работы обработчика события Timer каждый раз разное.
—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

Re: Не работает элементарный таймер

Сообщение alibek » 15.06.2013 (Сб) 9:55

Хакер писал(а):Он отсчитывается от конца работы обработчика события, а не от момента предыдущего срабатывания.

Это легко проверить. Правда нужен VB, а у меня его нет.
Нужно две программы, где используются таймеры с одинаковым интервалом, но разной длительностью выполнения обработчика.
Если таймеры будут тикать синхронно, значит «под шляпой» интервал задается перед выполнением обработчика. Если будет расхождения будут накопляться, значит «под шляпой» по завершении обработчика каждый раз заново задается таймаут.
Правда чтобы расхождение или синхронность были более наглядны, лучше использовать минимальные интервалы в 10мс. В обработчике использовать счетчик и выводить его значение.
Lasciate ogni speranza, voi ch'entrate.

aleksmir
Обычный пользователь
Обычный пользователь
 
Сообщения: 88
Зарегистрирован: 10.08.2009 (Пн) 13:17

Re: Не работает элементарный таймер

Сообщение aleksmir » 15.06.2013 (Сб) 13:01

alibek писал(а):
Хакер писал(а):Он отсчитывается от конца работы обработчика события, а не от момента предыдущего срабатывания.

Это легко проверить. Правда нужен VB, а у меня его нет.
Нужно две программы, где используются таймеры с одинаковым интервалом, но разной длительностью выполнения обработчика.
Если таймеры будут тикать синхронно, значит «под шляпой» интервал задается перед выполнением обработчика. Если будет расхождения будут накопляться, значит «под шляпой» по завершении обработчика каждый раз заново задается таймаут.
Правда чтобы расхождение или синхронность были более наглядны, лучше использовать минимальные интервалы в 10мс. В обработчике использовать счетчик и выводить его значение.


Я так и сказал) что вы сделали проблему из ничего. Да таймер будет срабатывать не раз секунду, а с запаздыванием. Поэтому нужно свойству Interval задать значение меньше секунды, например 100 миллисекунд и все будет ОК. Потому что функция Time вернет текущее время независимо от того, когда таймер к ней обратится.

След.

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

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

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

    TopList