таймер (событие вызываемое через определённое время)?

Предыдущая тема Следующая тема Перейти вниз

таймер (событие вызываемое через определённое время)?

Сообщение  Eric-S в Ср Сен 24, 2008 1:38 am

Привет!

Мне нужно каждую секунду или 0.1 секунды, обновлять строку статуса.

Строка статуса, формируеться и выводиться функцией status_bar.
Нужно её вызывать через каждую секунду.

Подскажите, как такое сделать?

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  Andrew в Ср Сен 24, 2008 11:17 pm

если я все правильно понял, то вродебы так (в цикле)

If Timing < Timer ' если переменная меньше
Timing = Timer + 0.1 ' добавляем в нее 1 милисек.
Status_Bar (a,b) ' вызываем твою функцию
EndIf

Andrew

Сообщения : 45
Дата регистрации : 2008-09-23
Возраст : 28
Откуда : Киев

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  Eric-S в Ср Сен 24, 2008 11:35 pm

Прошу прощенья, наверное я не очень хорошо объяснил.
Суть такая. Если вы смотрели мою прогу для записи с микрофона, то именно для неё.

Прога крутиться.
Я жду и обрабатываю нажатия клавиш.
А строка статуса должна обновляться.
Ну там например показать время от начала.

Сначало у меня вообще была мысль на счёт разделение потока.

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

Но может быть примерно такой вариант будет вполне нормальным?

Код:

do

sleep 50
select case inkey
case "p"
case "r"
case "s"
end select

status_bar
loop

Помню, что вывод на экран в qbasic и даже vb1 жутко тормозил прогу. А в freebasic должно быть лучше, но на сколько?

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  Замабувараев в Чт Сен 25, 2008 2:10 pm

В папке examples\events\timer есть пример многопоточного таймера. С ним стоит разобраться, но при использовании Wid32GIU приложений есть одна особенность. Обращение к свойствам элементов управления должно происходить в том же потоке, в котором создан сам элемент управления. Этот таймер будет вызывать функцию таймера в другом потоке, и нужно будет каким-то образом переадресовать вызов на основной поток.
avatar
Замабувараев

Сообщения : 99
Дата регистрации : 2008-08-20
Возраст : 33
Откуда : Красноярск

Посмотреть профиль http://www.freebasic.su

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  justar в Сб Сен 27, 2008 9:19 am

Помнится, в QB был оператор ON TIMER GOSUB, вызывавший подпрограмму по таймерному прерыванию. Интересно, почему в FB его не сделали?

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  tux в Сб Сен 27, 2008 4:56 pm

наверно потомушто времена доса прошли, а в венде ето мона сделать через апи
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  justar в Сб Сен 27, 2008 6:49 pm

Очень жаль. Когда пишешь что-то небольшое, простое, лезть в дебри ВинАПИ совсем не хочется... Более того, посмотрел озвученный тут пример... мало что понял на вскидку, а собрать и подёргать не получилось - не линкуется Sad

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  tux в Сб Сен 27, 2008 8:57 pm

просто винда (ХР в часности) не даст напрямую получать данные из биоса, как скорее всего делалось в QB, да и используются в винде не прерывания а сообщения, и хош нехош, а приходится етим пользоваться
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  tux в Сб Сен 27, 2008 8:58 pm

а када пишеш чето небольшое, то помоему достаточно sleep-а или timer-а (во всяком случае мне)
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  justar в Сб Сен 27, 2008 11:04 pm

tux пишет:просто винда (ХР в часности) не даст напрямую получать данные из биоса, как скорее всего делалось в QB, да и используются в винде не прерывания а сообщения, и хош нехош, а приходится етим пользоваться
В QB, по идее, обработчик просто подвешивался на прерывание таймера. И, вроде бы, код, создаваемый QB под ХР работает... А в FB почему то даже во встроенном асме обращаться к прерываниям нельзя...

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  justar в Сб Сен 27, 2008 11:05 pm

tux пишет:а када пишеш чето небольшое, то помоему достаточно sleep-а или timer-а (во всяком случае мне)
Это если нужны задержки. А когда надо с определённым интервалом прерывать основную программы=у в произвольном месте и выполнять что-то... не хватит (IMHO)

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  Eric-S в Вс Сен 28, 2008 12:09 am

Да, вот есть оказываеться такая проблемка.
Вероятно это из-за кросплатформенности или потому, что есть многопоточность.

Электрик, мне тут недавно говорил, что windows паузу с помощью winApi обрабатывает корректнее, а sleep больше грузит проц.

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

on timer конечно было удобно, но это не отвечает современным требованиям.

Eric-S

Сообщения : 738
Дата регистрации : 2008-08-06
Возраст : 34
Откуда : Россия, Санкт-Петербург

Посмотреть профиль http://eric50.narod.ru

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  tux в Вс Сен 28, 2008 7:45 am

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

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  tux в Вс Сен 28, 2008 7:48 am

Выясняеться, что в fb нужно ещё поработать над событиями
пардон, но помоему в FB ваще не существует обработки событий (или я ошибаюсь?)
avatar
tux

Сообщения : 365
Дата регистрации : 2008-04-06
Возраст : 29
Откуда : Сибирь

Посмотреть профиль http://tux.nsk.ru/

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  justar в Вс Сен 28, 2008 9:11 am

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

Если действительно необходимо прерывать подпрограмму, то проще сделать отдельный поток, который следит за таймером, и в зависимости от его значений вызывать в отдельном потоке подпрограммы, ну и соответственно тада мона будет ее завершить при желании в любой момент
IMHO, тоже не совсем то. В этом случае подпрограмма будет выполняться параллельно основной программе, а это может быть лишним и даже вредным (например, при использовании глобальных переменных возможен непредсказуемый результат). Болле того, если время выполнения подпрограммы больше заданного интервала вызова, то может получиться, что в какой-то момент времени будут запущенны несколько копий подпрограммы - а это уже светит трудно отлавливаемыми коллизиями. Что сделет Винда, если две разные задачи оновременно обратятся к одному и тому же устройству? Скорее всего выдаст "Access violation" и прибьёт одну из них (какую?). В общем, такой подход весьма сложен инеоднозначен даже под виндой, а уж если ставить задачу многоплатформености... Честное слово, старый добрый, ставший уже классикой Бейсика, ON TIMER выглядит на много приемлемее со всех точек зрения Wink

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  justar в Вс Сен 28, 2008 9:13 am

tux пишет:пардон, но помоему в FB ваще не существует обработки событий (или я ошибаюсь?)
IMHO, ошибаешься: ON ERROR - это ведь тоже обработчик события. Вот и непонятно - почему его в FB реализовали, а такие удобные вещи, как ON TIMER и ON SPRITE - нет...

justar

Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 43
Откуда : Кишинёв, Республика Молдоа

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  electrik в Вс Сен 28, 2008 11:47 am

привет. вот вам описание нескольких winapi функций работающих с таймером. предупреждаю, что все расчитано под visual basic, но знающие могут без труда переписать под FreeBasic.

SetTimer

Функция SetTimer
Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
SetTimer создает таймер с заданным значением интервала. Созданный таймер будет генерировать интервалы до тех пор, пока не будет вызвана функция
KillTimer,
удаляющая его. Использование этой функции необходимо там, где возможности встроенного vb-элемента управления Timer недостаточны. Элемент управления Timer
может использовать интервал чуть более одной минуты. А функция способна задать интервал в 24.86 дня!

Возвращаемое значение

В успешном случае функция возвращает значение идентификатора созданного таймера. В случае ошибки возвращается 0 (используйте GetLastError для получения кода ошибки)

Параметры
hWnd
Дескриптор окна для создаваемого таймера. Для создания таймера, не связанного с никаким окном используйте 0
nIDEvent
Ненулевое значение для задания идентификатора таймера. Если hWnd равен 0, то параметр игнорируется
uElapse
Интервал таймера в миллисекундах. Не превышайте предел 2 147 483 647 миллисекунд. Учтите, что физический таймер тикает приблизительно 18,21 раза
в секунду (точное значение составляет 1000/54,925). Поэтому, даже если вы укажете, что таймер должен тикать каждую миллисекунду, сообщения будут приходить
с интервалом не менее 55 миллисекунд
lpTimerFunc
Указатель на функцию обратного вызова TimerProc.
Если равен 0, то посылается сообщение WM_TIMER заданному окну

Пример
' Пример создания таймера
' Вставьте код в стандартный модуль
Declare Function SetTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As Long) As Long

Declare Function KillTimer Lib "user32" _
(ByVal hwnd As Long, _
ByVal nIDEvent As Long) As Long

Global iCounter As Integer

Sub TimerProc (ByVal hwnd As Long, _
ByVal uMsg As Long, _
ByVal idEvent As Long, _
ByVal dwTime As Long)

iCounter = iCounter + 1
Form1.Text1.Text = CStr(iCounter)
End Sub


' Добавьте на форму кнопку Command1
' и текстовое поле Text1

Dim lngTimerID As Long
Dim BlnTimer As Boolean

Private Sub Form_Load()
BlnTimer = False
Command1.Caption = "Включить таймер"
End Sub

Private Sub Command1_Click()
' Включаем и выключаем таймер

If BlnTimer = False Then
lngTimerID = SetTimer(0, 0, 200, AddressOf TimerProc)
If lngTimerID = 0 Then
MsgBox "Таймер не создан. Конец программы"
Exit Sub
End If
BlnTimer = True
Command1.Caption = "Выключить таймер"
Else
lngTimerID =
KillTimer
(0, lngTimerID)
If lngTimerID = 0 Then
MsgBox "Не могу убить таймер"
End If
BlnTimer = False
Command1.Caption = "Включить таймер"
End If

End Sub

Смотри также
KillTimer


KillTimer

Функция KillTimer
Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
KillTimer уничтожает заданный таймер, созданный функцией
SetTimer
hWnd
Дескриптор окна для заданного таймера. Должен иметь значение, полученное функцией
SetTimer

uIDEvent
Если таймер принадлежит окну, то параметр является идентификатором таймера, полученный функцией
SetTimer.
Если таймер не имеет окна, то это значение будут получено при вызове функции
SetTimer

Пример
' Пример использования функции смотри
' в описании функции
SetTimer

Смотри также
SetTimer


QueryPerformanceCounter

Функция QueryPerformanceCounter
Declare Function QueryPerformanceCounter Lib "kernel32.dll" (lpPerformanceCount As Currency) As Long
QueryPerformanceCounter позволяет получить значение системного высокоточного таймера. Системный высокоточный таймер - это счетчик, позволяющий измерять
очень маленькие интервалы времени с большой точностью. Точность времени очень сильно зависит от конкретного оборудования. Узнать, насколько точны интервалы
времени можно с помощью
QueryPerformanceFrequency,
возвращающей число тактов в секунду. Зная эту частоту, вы можете использовать высокоточный таймер
lpPerformanceCount64-битное значение таймера. Мы используем для удобства тип Currency
Пример
' Вычислим время необходимое для длительных вычислений
Dim i ' счетчик для вычислений
Dim freq as Currency ' частота, генерируемая компьютером
Dim mystart As Currency, mystop As Currency ' начальное и конечные значения счетчика

If QueryPerformanceFrequency (freq) = 0 Then
MsgBox "Ваш компьютер не поддерживает высокоточный таймер!"
End If

QueryPerformanceFrequency freq
QueryPerformanceCounter mystart ' начальное значение счетчика
' Проводим длительные вычисления
For i = 1 To 7500000
i = i + 1
Next

QueryPerformanceCounter mystop ' конечное значение счетчика
' Вычисляем интервал, которое понадобилось для длительного вычисления
' Для этого вычитаем начальное значение из конечного
' и делим на частоту таймера
MsgBox (mystop - mystart) / freq & " сек."
Смотри также
QueryPerformanceFrequency


QueryPerformanceFrequency

Функция QueryPerformanceFrequency
Declare Function QueryPerformanceFrequency Lib "kernel32.dll" (lpFrequency As Currency) As Long
QueryPerformanceFrequency определяет частоту системного высокоточного таймера. Зная число тактов в секунду с помощью этой функции, вы можете использовать
высокоточный таймер при использовании
QueryPerformanceCounter.
Не все компьютеры поддерживают высокоточный таймер
lpFrequencyПолучает 64-битную частоту (число тактов в секунду), если существует подобный таймер
Пример
' Вычислим частоту таймер
Dim freq as Currency ' частота, генерируемая компьютером

If QueryPerformanceFrequency(freq) = 0 Then
MsgBox "Ваш компьютер не поддерживает высокоточный таймер!"
End If

QueryPerformanceFrequency freq

Print freq ' получаем значение частоты
Смотри также
QueryPerformanceCounter

electrik

Сообщения : 391
Дата регистрации : 2008-09-02
Возраст : 36
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  ruddy в Вт Янв 21, 2014 10:53 am

Друзья, чуть больше года назад познакомился с компилятором FreeBASIC – штука отличная! Но вполне разделяю тревогу "justar", написавшего 28.09.2008, что ему непонятно почему в FB не реализованы такие удобные вещи, как ON TIMER и ON SPRITE... Если использовать персональный компьютер по его прямому назначению, т.е. для оперативного решения вычислительных задач, то IMHO "мультимедийные" способности компилятора становятся не так уж и важны по сравнению с его способностью поддерживать "событийно-ориентированное" программирование. При этом механизмы поддержки должны быть максимально прозрачны и не отвлекать от работы по реализации целевого (основного) алгоритма.

Отдавая должное усилиям "electrik", хочу нижайше попросить его, для людей далеких от систематического программирования, написать краткое наставление по ключевым моментам организации событийно-ориентированных программ под FreeBASIC.
avatar
ruddy

Сообщения : 15
Дата регистрации : 2011-11-14
Откуда : Москва

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: таймер (событие вызываемое через определённое время)?

Сообщение  Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения