Вверх ↑
Этот топик читают: Гость
Ответов: 215
Рейтинг: 6
#1: 2026-02-10 09:56:58 ЛС | профиль | цитата
Всем привет. Столкнулся с непонятным поведением таймера в данной ситуации. Он не запускается. Что это? Пробовал пересоздать таймер не помогло.


Add(MultiElement,16056968,343,210)
{
@Color=43775
link(onEvent2,10085835:doEvent1,[])
}
BEGIN_SDK
Add(EditMulti,3920564,21,21)
{
EventCount=2
WorkCount=1
Width=412
link(doWork1,9210074:doData,[(87,27)(87,139)])
}
Add(WinExec,13023946,154,119)
{
FileName="powershell"
Param="-nologo -noprofile -command "& {(Get-PnpDevice -PresentOnly -InstanceId 'USB\VID_0483"&"PID_5740*').Name }""
Mode=0
Point(doConsoleExec)
Point(onConsoleResult)
Point(onConsoleError)
link(onConsoleResult,1345852:doCharset,[])
link(onConsoleError,14212254:doCharset,[(223,146)(223,181)])
}
Add(Charset,1345852,231,133)
{
link(onCharset,3780311:doSearch,[])
}
Add(Charset,14212254,231,175)
{
link(onCharset,3867453:doSearch,[(275,181)(275,188)])
}
Add(BlockFind,3867453,287,182)
{
StartBlock="не удалось"
EndBlock="обнаружить"
link(onSearch,568899:doData,[])
}
Add(DoData,568899,329,182)
{
@Color=43775
Data=String()
link(onEventData,1466602:doWork3,[(376,188)])
}
Add(DoData,9210074,112,133)
{
link(onEventData,13023946:doConsoleExec,[])
}
Add(BlockFind,3780311,287,133)
{
IncludeBlock=1
StartBlock="("
EndBlock=")"
Point(onNotFind)
Point(doStop)
link(onSearch,4082409:doEvent1,[])
link(onNotFind,1466602:doWork2,[])
}
Add(Hub,4082409,329,133)
{
link(onEvent1,3780311:doStop,[(347,139)(347,125)(275,125)(275,146)])
link(onEvent2,3920564:onEvent1,[(388,146)(388,27)])
}
Add(HubEx,1466602,372,147)
{
Angle=3
link(onEvent,3920564:onEvent2,[(376,34)])
}
END_SDK
Add(Timer,5674699,441,210)
{
Interval=500
Enable=1
AutoStop=1
Point(onStop)
link(onTimer,16196945:doData,[])
link(onStop,15408543:In,[])
}
Add(Button,6789410,287,210)
{
Left=65
Top=85
link(onClick,16056968:doWork1,[])
}
Add(Hub,10085835,399,217)
{
link(onEvent1,5674699:doTimer,[(427,223)(427,216)])
link(onEvent2,5302195:doData,[])
}
Add(Hub,13166820,686,210)
{
InCount=3
OutCount=1
link(onEvent1,15061016:doAdd,[])
}
Add(HilightMemo,15061016,791,210)
{
Left=165
Top=70
Width=215
Height=185
Font=[Courier New,8,0,0,1]
HilightFont=[Courier New,8,0,0,1]
}
Add(DoData,16196945,630,210)
{
Data=String(123)
link(onEventData,13166820:doEvent1,[])
}
Add(DoData,5302195,567,224)
{
Data=String(333)
link(onEventData,13166820:doEvent2,[(643,230)(643,223)])
}
Add(LineBreak,10818245,588,280)
{
link(Out,2330533:doData,[])
Primary=[15408543,-105,-63]
}
Add(DoData,2330533,637,280)
{
Data=String(стоп)
link(onEventData,13166820:doEvent3,[(677,286)(677,230)])
}

карма: 1
Сообщество Hiasm в VK hhttps://vk.com/club_hiasm (компоненты, статьи, схемы).
0
Ответов: 1061
Рейтинг: 219
#2: 2026-02-10 14:33:58 ЛС | профиль | цитата
strannik_nebes писал(а):
олкнулся с непонятным поведением таймера в данной ситуации. Он не запускается. Что это?

А так?

Add(MainForm,15139245,168,105)
{
}
Add(MultiElement,16056968,322,105)
{
@Color=43775
link(onEvent2,5569307:doDeferredEvent,[])
}
BEGIN_SDK
Add(EditMulti,3920564,21,21)
{
EventCount=2
WorkCount=1
Width=412
link(doWork1,9210074:doData,[(102,27)(102,139)])
}
Add(WinExec,13023946,154,119)
{
FileName="powershell"
Param="-nologo -noprofile -command "& {(Get-PnpDevice -PresentOnly -InstanceId 'USB\VID_0483"&"PID_5740*').Name }""
Mode=0
Point(doConsoleExec)
Point(onConsoleResult)
Point(onConsoleError)
link(onConsoleResult,1345852:doCharset,[])
link(onConsoleError,14212254:doCharset,[(223,146)(223,181)])
}
Add(Charset,1345852,231,133)
{
link(onCharset,3780311:doSearch,[])
}
Add(Charset,14212254,231,175)
{
link(onCharset,3867453:doSearch,[(275,181)(275,188)])
}
Add(BlockFind,3867453,287,182)
{
StartBlock="не удалось"
EndBlock="обнаружить"
link(onSearch,568899:doData,[])
}
Add(DoData,568899,329,182)
{
@Color=43775
Data=String()
link(onEventData,1466602:doWork3,[(376,188)])
}
Add(DoData,9210074,105,133)
{
link(onEventData,13023946:doConsoleExec,[])
}
Add(BlockFind,3780311,287,133)
{
IncludeBlock=1
StartBlock="("
EndBlock=")"
Point(onNotFind)
Point(doStop)
link(onSearch,4082409:doEvent1,[])
link(onNotFind,1466602:doWork2,[])
}
Add(Hub,4082409,329,133)
{
link(onEvent1,3780311:doStop,[(347,139)(347,125)(275,125)(275,146)])
link(onEvent2,3920564:onEvent1,[(388,146)(388,27)])
}
Add(HubEx,1466602,372,147)
{
Angle=3
link(onEvent,3920564:onEvent2,[(376,34)])
}
END_SDK
Add(Timer,5674699,476,105)
{
Interval=500
Enable=1
AutoStop=1
Point(onStop)
link(onTimer,16196945:doData,[])
link(onStop,15408543:In,[])
}
Add(Button,6789410,266,105)
{
Left=65
Top=85
link(onClick,16056968:doWork1,[])
}
Add(Hub,10085835,434,112)
{
link(onEvent1,5674699:doTimer,[(462,118)(462,111)])
link(onEvent2,5302195:doData,[])
}
Add(Hub,13166820,721,105)
{
InCount=3
OutCount=1
link(onEvent1,15061016:doAdd,[])
}
Add(HilightMemo,15061016,826,105)
{
Left=165
Top=70
Width=215
Height=185
Font=[Courier New,8,0,0,1]
HilightFont=[Courier New,8,0,0,1]
}
Add(DoData,16196945,665,105)
{
Data=String(123)
link(onEventData,13166820:doEvent1,[])
}
Add(DoData,5302195,602,119)
{
Data=String(333)
link(onEventData,13166820:doEvent2,[(678,125)(678,118)])
}
Add(LineBreak,5329229,623,175)
{
link(Out,2330533:doData,[])
Primary=[15408543,-105,-63]
}
Add(DoData,2330533,672,175)
{
Data=String(стоп)
link(onEventData,13166820:doEvent3,[(712,181)(712,125)])
}
Add(DeferredEvent,5569307,378,112)
{
link(onDeferredEvent,10085835:doEvent1,[])
}

карма: 20

1
Голосовали:strannik_nebes
Ответов: 1061
Рейтинг: 219
#3: 2026-02-10 17:49:55 ЛС | профиль | цитата
strannik_nebes, Попробуй эту схему. Определение названия устройства по VID и PID.
Не забудь прописать данные своего устройства. У меня находит полное название.
Работает быстрее чем PowerShell. IC мой потому могут быть ошибки.
https://forum.hiasm.com/getfile/40616
карма: 20

0
файлы: 1Get Device Name.zip [1.6KB] [51]
Ответов: 4673
Рейтинг: 768
#4: 2026-02-11 14:08:38 ЛС | профиль | цитата
Схему не смотрел, попробую предположить.
Обычный таймер нельзя запускать из параллельного потока.

Если в данной схеме таймер включается по событиях onConsoleXXX, то они как раз происходят в пар. потоке.
Тогда в линк включения таймера нужно вставить компонент Synchronize. Компонент DeferredEvent делает то же самое, только другим путем.
карма: 26

0
Ответов: 215
Рейтинг: 6
#5: 2026-02-12 08:34:25 ЛС | профиль | цитата
Gunta, Спасибо за помощь. По сути, можно элемент создать на базе этого кода.

1. Я доработал чуток схему, чтобы можно получить информацию обо всех подключенных устройств такого типа, в делфи я не шарю, чисто опираясь на язык С/С++.

Add(MainForm,13673400,175,182)
{
Width=300
Height=200
link(onCreate,12929181:doCheck,[])
}
Add(InlineCode,12929181,245,196)
{
WorkPoints=#7:doCheck|
EventPoints=#7:onCheck|
DataPoints=#7:VID_PID|
Code=#15:unit HiAsmUnit;|0:|9:interface|0:|38:uses kol,Windows,Share,Debug,Messages;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|11:VP: String;|0:|9: public|0:|26:onCheck,VID_PID:THI_Event;|48:Procedure doCheck (var _Data:TData; Index:word);|0:|5: end;|0:|5:const|36: DIGCF_PRESENT = $00000002;|36: DIGCF_ALLCLASSES = $00000004;|2: |36: SPDRP_DEVICEDESC = $00000000;|36: SPDRP_HARDWAREID = $00000001;|36: SPDRP_FRIENDLYNAME = $0000000C;|36: SPDRP_LOCATION_INFO = $0000000D;|0:|4:type|25: TSPDevInfoData = record|18: cbSize: DWORD;|21: ClassGuid: TGUID;|19: DevInst: DWORD;|24: Reserved: LongWord; |6: end;|0:|169:function SetupDiGetClassDevs(ClassGuid: PGUID; Enumerator: PChar; hwndParent: HWND; Flags: DWORD): THandle; stdcall; external 'setupapi.dll' name 'SetupDiGetClassDevsA';|180:function SetupDiEnumDeviceInfo(DeviceInfoSet: THandle; MemberIndex: DWORD; var DeviceInfoData: TSPDevInfoData): BOOL; stdcall; external 'setupapi.dll' name 'SetupDiEnumDeviceInfo';|247:function SetupDiGetDeviceInstanceId(DeviceInfoSet: THandle; var DeviceInfoData: TSPDevInfoData; DeviceInstanceId: PChar; DeviceInstanceIdSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall; external 'setupapi.dll' name 'SetupDiGetDeviceInstanceIdA';|302:function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: THandle; var DeviceInfoData: TSPDevInfoData; Property_: DWORD; PropertyRegDataType: PDWORD; PropertyBuffer: PByte; PropertyBufferSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall; external 'setupapi.dll' name 'SetupDiGetDeviceRegistryPropertyA';|138:function SetupDiDestroyDeviceInfoList(DeviceInfoSet: THandle): BOOL; stdcall; external 'setupapi.dll' name 'SetupDiDestroyDeviceInfoList';|0:|0:|0:|14:implementation|0:|61:Procedure THiAsmClass.doCheck (var _Data:TData; Index:word);|3:var|22: DevInfoSet: THandle;|30: DevInfoData: TSPDevInfoData;|13: i: Integer;|33: Buffer: array[0..1024] of Char;|37: S_InstId, S_Target,NameStr: String;|2: |45: function TryGetProp(PropID: DWORD): String;|7: begin|40: FillChar(Buffer, SizeOf(Buffer), 0);|119: if SetupDiGetDeviceRegistryProperty(DevInfoSet, DevInfoData, PropID, nil, PByte(@Buffer), SizeOf(Buffer), nil) then|30: Result := String(Buffer)|8: else|19: Result := '';|6: end;|0:|5:begin|16: NameStr := '';|40: S_Target := ReadString(_Data,VID_PID);|40: //S_Target := 'USB\VID_1A86&PID_7523';|2: |84: DevInfoSet := SetupDiGetClassDevs(nil, nil, 0, DIGCF_PRESENT or DIGCF_ALLCLASSES);|49: if DevInfoSet = INVALID_HANDLE_VALUE then Exit;|0:|27: DevInfoData.cbSize := 28;|9: i := 0;|2: |60: while SetupDiEnumDeviceInfo(DevInfoSet, i, DevInfoData) do|7: begin|44:// _hi_OnEvent (onCheck,i); //idx|40: FillChar(Buffer, SizeOf(Buffer), 0);|92: if SetupDiGetDeviceInstanceId(DevInfoSet, DevInfoData, Buffer, SizeOf(Buffer), nil) then|9: begin|44: S_InstId := UpperCase(String(Buffer));|5: |41: if Pos(S_Target, S_InstId) > 0 then|11: begin|50: NameStr := TryGetProp(SPDRP_FRIENDLYNAME);|69: if NameStr = '' then NameStr := TryGetProp(SPDRP_DEVICEDESC);|69: if NameStr = '' then NameStr := TryGetProp(SPDRP_HARDWAREID);|49: if NameStr = '' then NameStr := S_InstId;|32: _hi_OnEvent (onCheck,NameStr) |16:// Break;|10: end;|8: end;|11: Inc(i);|6: end;|4:end;|0:|4:end.|
link(onCheck,13756087:doAdd,[])
link(VID_PID,16453930:Text,[(251,146)(195,146)])
}
Add(Memo,13756087,336,196)
{
Left=75
Top=45
Width=280
Height=200
Align=5
Font=[Lucida Console,12,0,0,204]
Antialiased=1
ScrollBars=3
}
Add(VisualStrings,12293096,266,140)
{
Lines=#21:USB\VID_1A86&PID_7523|
Width=144
}
Add(VisualStrings,3173068,245,105)
{
Lines=#21:USB\VID_0483&PID_5740|
Width=151
}
Add(VisualStrings,16453930,189,77)
{
Lines=#7:USB\VID|
Width=151
}

2. Netspirit, да таймер включается по событиях onConsoleXXX. С Synchronize не работает. А вот с DeferredEvent срабатывает, Gunta, как раз такой вариант решения проблемы и предложил

Редактировалось 2 раз(а), последний 2026-02-12 08:37:38
карма: 1
Сообщество Hiasm в VK hhttps://vk.com/club_hiasm (компоненты, статьи, схемы).
0
Ответов: 4673
Рейтинг: 768
#6: 2026-02-15 19:01:10 ЛС | профиль | цитата
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 не имеет такой особенности, так как работает по другому принципу.

Редактировалось 2 раз(а), последний 2026-02-15 19:06:59
карма: 26

0
Разработчик
Ответов: 26328
Рейтинг: 2148
#7: 2026-02-15 20:18:42 ЛС | профиль | цитата
Netspirit писал(а):
Synchronize/DeferredEvent - это происходит из главного потока (который создавался при запуске программы)

Тут немного уточню. DeferredEvent создает окно верхнего уровня при создании программы и не зависит от параллельных потоков, созданных позднее, а значит, должен отрабатывать без проблем сообщения из параллельных потоков. К тому же, он ставит сообщения в следующую очередь обработки, те все его сообщения отложенные.
карма: 22

0
7
Сообщение
...
Прикрепленные файлы
(файлы не залиты)