Add(Button,2947416,280,140){
Left=15
Top=15
Width=100
Caption="Не работает"
link(onClick,6368651:doConsoleExec,[])
}
Add(Button,3483132,280,301)
{
Left=15
Top=65
Width=100
Caption="Работает"
link(onClick,8221405:doConsoleExec,[])
}
Add(Label,8665776,525,140)
{
Left=130
Top=20
Width=10
Height=17
Caption="0"
}
Add(Label,8830409,588,301)
{
Left=130
Top=70
Caption="0"
}
Add(Timer,12527404,420,140)
{
Interval=500
Enable=1
AutoStop=10
link(onTimer,3016590:doNext,[])
}
Add(CounterEx,3016590,469,140)
{
Max=999999
link(onNext,8665776:doText,[])
}
Add(Timer,10506426,483,301)
{
Interval=500
Enable=1
AutoStop=10
link(onTimer,10638060:doNext,[])
}
Add(CounterEx,10638060,532,301)
{
Max=999999
link(onNext,8830409:doText,[])
}
Add(Synchronize,11047820,420,301)
{
link(onSync,10506426:doTimer,[])
}
Add(WinExec,8221405,343,287)
{
FileName="cmd.exe"
Param="/c "echo BLA-BLA-BLA""
Point(doConsoleExec)
Point(onConsoleResult)
link(onConsoleResult,11047820:doSynchronize,[])
AddHint(-14,-45,44,13,RunEvent)
AddHint(50,-47,55,13,FileName)
AddHint(120,-47,132,13,Param)
}
Add(WinExec,6368651,350,126)
{
FileName="cmd.exe"
Param="/c "echo BLA-BLA-BLA""
Point(doConsoleExec)
Point(onConsoleResult)
link(onConsoleResult,12527404:doTimer,[])
AddHint(-14,-45,44,13,RunEvent)
AddHint(50,-47,55,13,FileName)
AddHint(120,-47,132,13,Param)
}
Add(Button,9506597,287,462)
{
Left=15
Top=120
Width=100
Caption="Работает 2"
link(onClick,12423401:doTimer,[])
}
Add(Label,4247221,455,462)
{
Left=125
Top=125
Caption="0"
}
Add(Timer,12423401,350,462)
{
Interval=500
Enable=1
AutoStop=10
link(onTimer,14090721:doNext,[])
}
Add(CounterEx,14090721,399,462)
{
Max=999999
link(onNext,4247221:doText,[])
}
Если сначала нажать "Не работает", то можно увидеть что таймер не запустился, как и предполагалось.
Если после этого нажать "Работает" - то таймер все равно не запустится. Более того, после уже ни один таймер не запустится.
Если же сначала нажать "Работает" или "Работает 2", то после этого будут работать все таймеры, даже из параллельного потока без Synchronize/DeferredEvent.
Причина в том, что для получения событий таймер создаёт окно, куда приходят сообщения. Окно создается 1 раз на всю программу при первом включении любого таймера.
И если первый раз таймер включить из параллельного потока, то окно создаётся из этого потока и сообщения приходят в очередь этого же потока. Но параллельный поток не для того создавался и не подозревает, что ему нужно обрабатывать оконные сообщения.
После того как поток завершится, сообщения окна таймера вообще некому обрабатывать и все последуюшие таймеры перестают выдавать события.
Когда же мы первый раз включаем таймер кнопкой или Synchronize/DeferredEvent - это происходит из главного потока (который создавался при запуске программы). Этот поток занимается обработкой сообщений от элементов пользовательского интерфейса, в том числе и от окна таймера. А сообщения окну таймера приходят в этот главный поток и всё работает как надо.
MMTimer не имеет такой особенности, так как работает по другому принципу.



Поиск
Друзья
Администрация