таймер (событие вызываемое через определённое время)?
+3
Замабувараев
Andrew
Eric-S
Участников: 7
FreeBasic :: Программирование :: Общее
Страница 1 из 1
таймер (событие вызываемое через определённое время)?
Привет!
Мне нужно каждую секунду или 0.1 секунды, обновлять строку статуса.
Строка статуса, формируеться и выводиться функцией status_bar.
Нужно её вызывать через каждую секунду.
Подскажите, как такое сделать?
Мне нужно каждую секунду или 0.1 секунды, обновлять строку статуса.
Строка статуса, формируеться и выводиться функцией status_bar.
Нужно её вызывать через каждую секунду.
Подскажите, как такое сделать?
Re: таймер (событие вызываемое через определённое время)?
если я все правильно понял, то вродебы так (в цикле)
If Timing < Timer ' если переменная меньше
Timing = Timer + 0.1 ' добавляем в нее 1 милисек.
Status_Bar (a,b) ' вызываем твою функцию
EndIf
If Timing < Timer ' если переменная меньше
Timing = Timer + 0.1 ' добавляем в нее 1 милисек.
Status_Bar (a,b) ' вызываем твою функцию
EndIf
Andrew- Сообщения : 45
Дата регистрации : 2008-09-23
Возраст : 35
Откуда : Киев
Re: таймер (событие вызываемое через определённое время)?
Прошу прощенья, наверное я не очень хорошо объяснил.
Суть такая. Если вы смотрели мою прогу для записи с микрофона, то именно для неё.
Прога крутиться.
Я жду и обрабатываю нажатия клавиш.
А строка статуса должна обновляться.
Ну там например показать время от начала.
Сначало у меня вообще была мысль на счёт разделение потока.
Может быть я даже воспользуюсь другим вариантом, который мне только что пришол в голову.
Andrew , именно ваш пост, натолкнул меня на мысль, благодарю.
Но может быть примерно такой вариант будет вполне нормальным?
Помню, что вывод на экран в qbasic и даже vb1 жутко тормозил прогу. А в freebasic должно быть лучше, но на сколько?
Суть такая. Если вы смотрели мою прогу для записи с микрофона, то именно для неё.
Прога крутиться.
Я жду и обрабатываю нажатия клавиш.
А строка статуса должна обновляться.
Ну там например показать время от начала.
Сначало у меня вообще была мысль на счёт разделение потока.
Может быть я даже воспользуюсь другим вариантом, который мне только что пришол в голову.
Andrew , именно ваш пост, натолкнул меня на мысль, благодарю.
Но может быть примерно такой вариант будет вполне нормальным?
- Код:
do
sleep 50
select case inkey
case "p"
case "r"
case "s"
end select
status_bar
loop
Помню, что вывод на экран в qbasic и даже vb1 жутко тормозил прогу. А в freebasic должно быть лучше, но на сколько?
Re: таймер (событие вызываемое через определённое время)?
В папке examples\events\timer есть пример многопоточного таймера. С ним стоит разобраться, но при использовании Wid32GIU приложений есть одна особенность. Обращение к свойствам элементов управления должно происходить в том же потоке, в котором создан сам элемент управления. Этот таймер будет вызывать функцию таймера в другом потоке, и нужно будет каким-то образом переадресовать вызов на основной поток.
Re: таймер (событие вызываемое через определённое время)?
Помнится, в QB был оператор ON TIMER GOSUB, вызывавший подпрограмму по таймерному прерыванию. Интересно, почему в FB его не сделали?
justar- Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 50
Откуда : Кишинёв, Республика Молдоа
Re: таймер (событие вызываемое через определённое время)?
наверно потомушто времена доса прошли, а в венде ето мона сделать через апи
Re: таймер (событие вызываемое через определённое время)?
Очень жаль. Когда пишешь что-то небольшое, простое, лезть в дебри ВинАПИ совсем не хочется... Более того, посмотрел озвученный тут пример... мало что понял на вскидку, а собрать и подёргать не получилось - не линкуется
justar- Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 50
Откуда : Кишинёв, Республика Молдоа
Re: таймер (событие вызываемое через определённое время)?
просто винда (ХР в часности) не даст напрямую получать данные из биоса, как скорее всего делалось в QB, да и используются в винде не прерывания а сообщения, и хош нехош, а приходится етим пользоваться
Re: таймер (событие вызываемое через определённое время)?
а када пишеш чето небольшое, то помоему достаточно sleep-а или timer-а (во всяком случае мне)
Re: таймер (событие вызываемое через определённое время)?
В QB, по идее, обработчик просто подвешивался на прерывание таймера. И, вроде бы, код, создаваемый QB под ХР работает... А в FB почему то даже во встроенном асме обращаться к прерываниям нельзя...tux пишет:просто винда (ХР в часности) не даст напрямую получать данные из биоса, как скорее всего делалось в QB, да и используются в винде не прерывания а сообщения, и хош нехош, а приходится етим пользоваться
justar- Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 50
Откуда : Кишинёв, Республика Молдоа
Re: таймер (событие вызываемое через определённое время)?
Это если нужны задержки. А когда надо с определённым интервалом прерывать основную программы=у в произвольном месте и выполнять что-то... не хватит (IMHO)tux пишет:а када пишеш чето небольшое, то помоему достаточно sleep-а или timer-а (во всяком случае мне)
justar- Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 50
Откуда : Кишинёв, Республика Молдоа
Re: таймер (событие вызываемое через определённое время)?
Да, вот есть оказываеться такая проблемка.
Вероятно это из-за кросплатформенности или потому, что есть многопоточность.
Электрик, мне тут недавно говорил, что windows паузу с помощью winApi обрабатывает корректнее, а sleep больше грузит проц.
Выясняеться, что в fb нужно ещё поработать над событиями, а событиями таймера особенно.
Потому, что если вы загляните в програмку, которая демонстрирует это, то придёте в ужас, также как и я.
on timer конечно было удобно, но это не отвечает современным требованиям.
Вероятно это из-за кросплатформенности или потому, что есть многопоточность.
Электрик, мне тут недавно говорил, что windows паузу с помощью winApi обрабатывает корректнее, а sleep больше грузит проц.
Выясняеться, что в fb нужно ещё поработать над событиями, а событиями таймера особенно.
Потому, что если вы загляните в програмку, которая демонстрирует это, то придёте в ужас, также как и я.
on timer конечно было удобно, но это не отвечает современным требованиям.
Re: таймер (событие вызываемое через определённое время)?
ну так в цикле мона проверять разность значений timer-а (помоему выше так рекомендовалось), и как будет нужная разница, сохнаять новое значение и вызывать необходимую подпрограмму, после ее завершения опять обрабатывать значения таймера, + к этому будет гарантия, что подпрограмма не оборвется из за прерывания на половине работы (или вы етого и хотите?). Если действительно необходимо прерывать подпрограмму, то проще сделать отдельный поток, который следит за таймером, и в зависимости от его значений вызывать в отдельном потоке подпрограммы, ну и соответственно тада мона будет ее завершить при желании в любой моментс определённым интервалом прерывать основную программы
Re: таймер (событие вызываемое через определённое время)?
пардон, но помоему в FB ваще не существует обработки событий (или я ошибаюсь?)Выясняеться, что в fb нужно ещё поработать над событиями
Re: таймер (событие вызываемое через определённое время)?
Громозко (цикл должен быть от начала до конца программы) и всё равно не позволяет выполнить обработчик прерывания в заданный временой интервал - а только лишь спустя него после завершения очередного програмного цикла. А это совсем не то. Скажем, в играх ещё подойдёт... но в программах реального времени этого недостаточно: например, когда программа должна с заданным интервалом считывать очередной квант данных с порта - если ориентироваться просто на большее заданного время (что и получится в твоём варианте), то можно прозевать очередной квант, который на момен проверки таймера уже окажется затёртым следующим. Понятно, что под Виндой можно создать собственное событие, заставить Винду посылать его программе по заданным интервалам таймера (а лучше - по обновлению данных в порту) - и быть счастливым. Но!! Во-первых, а если я не хочу Win32GUI, а просто хочу сам всё нарисовать на графическом экране? Во-вторых, я, может, хочу кроссплатформенную прогу написать... Как быть в этих случаях?tux пишет:ну так в цикле мона проверять разность значений timer-а
IMHO, тоже не совсем то. В этом случае подпрограмма будет выполняться параллельно основной программе, а это может быть лишним и даже вредным (например, при использовании глобальных переменных возможен непредсказуемый результат). Болле того, если время выполнения подпрограммы больше заданного интервала вызова, то может получиться, что в какой-то момент времени будут запущенны несколько копий подпрограммы - а это уже светит трудно отлавливаемыми коллизиями. Что сделет Винда, если две разные задачи оновременно обратятся к одному и тому же устройству? Скорее всего выдаст "Access violation" и прибьёт одну из них (какую?). В общем, такой подход весьма сложен инеоднозначен даже под виндой, а уж если ставить задачу многоплатформености... Честное слово, старый добрый, ставший уже классикой Бейсика, ON TIMER выглядит на много приемлемее со всех точек зренияЕсли действительно необходимо прерывать подпрограмму, то проще сделать отдельный поток, который следит за таймером, и в зависимости от его значений вызывать в отдельном потоке подпрограммы, ну и соответственно тада мона будет ее завершить при желании в любой момент
justar- Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 50
Откуда : Кишинёв, Республика Молдоа
Re: таймер (событие вызываемое через определённое время)?
IMHO, ошибаешься: ON ERROR - это ведь тоже обработчик события. Вот и непонятно - почему его в FB реализовали, а такие удобные вещи, как ON TIMER и ON SPRITE - нет...tux пишет:пардон, но помоему в FB ваще не существует обработки событий (или я ошибаюсь?)
justar- Сообщения : 135
Дата регистрации : 2008-05-12
Возраст : 50
Откуда : Кишинёв, Республика Молдоа
Re: таймер (событие вызываемое через определённое время)?
привет. вот вам описание нескольких 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
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
Возраст : 43
Откуда : галактика Млечный путь, система Солнечная, планета Земля, страна россия, город Санкт Петербург
Re: таймер (событие вызываемое через определённое время)?
Друзья, чуть больше года назад познакомился с компилятором FreeBASIC – штука отличная! Но вполне разделяю тревогу "justar", написавшего 28.09.2008, что ему непонятно почему в FB не реализованы такие удобные вещи, как ON TIMER и ON SPRITE... Если использовать персональный компьютер по его прямому назначению, т.е. для оперативного решения вычислительных задач, то IMHO "мультимедийные" способности компилятора становятся не так уж и важны по сравнению с его способностью поддерживать "событийно-ориентированное" программирование. При этом механизмы поддержки должны быть максимально прозрачны и не отвлекать от работы по реализации целевого (основного) алгоритма.
Отдавая должное усилиям "electrik", хочу нижайше попросить его, для людей далеких от систематического программирования, написать краткое наставление по ключевым моментам организации событийно-ориентированных программ под FreeBASIC.
Отдавая должное усилиям "electrik", хочу нижайше попросить его, для людей далеких от систематического программирования, написать краткое наставление по ключевым моментам организации событийно-ориентированных программ под FreeBASIC.
ruddy- Сообщения : 15
Дата регистрации : 2011-11-14
Откуда : Москва
FreeBasic :: Программирование :: Общее
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения