Что нового

GUICtrlSendToDummy для скрытых окон возможна замена на GUICtrlSendMsg?

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Обнаружил что GUICtrlSendToDummy не будет работать, если окно скрыто(невидимо) :stars:
Поэтому для такого "приемника" сообщений необходим показ окна:
Код:
Opt('GUIOnEventMode', 1)
Global Const $TITLE_RECEIVER = '#Reseiver'
Global Const $WM_COPYDATA = 0x004A
Global $hForm = GUICreate($TITLE_RECEIVER,0,0,10,10)
Global $DUMMY_MAIN = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "MAIN_DUMMY_EVENT")
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
GUISetState()
While 1
	Sleep(250)
WEnd
Func MAIN_DUMMY_EVENT()
	ConsoleWrite(GUICtrlRead($DUMMY_MAIN) & @LF)
EndFunc   ;==>MAIN_DUMMY_EVENT
Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
	Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
	Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
	$sMsg = DllStructGetData($tMsg, 1)
	GUICtrlSendToDummy($DUMMY_MAIN, $sMsg)
EndFunc   ;==>_WM_COPYDATA


Но т.к я не хочу, что бы было окно видимым, то этот пример не работает.
Можно ли решить это недорозумение как нибудь с помощью GUICtrlSendMsg?
Я конечно понимаю, что окно можно сдвинуть за границы экрана, но пока не хочу это делать.

P.s вот код отправителя
Код:
Global Const $WM_COPYDATA = 0x004A
Global Const $TITLE_RECEIVER = '#Reseiver'
$hWnd = WinGetHandle($TITLE_RECEIVER)
_SendData($hWnd, 'ТЕСТ')
func _SendData($hWnd, $sData)
    local $tCOPYDATA, $tMsg
    $tMsg = DllStructCreate('char[' & StringLen($sData) + 1 & ']')
    DllStructSetData($tMsg, 1, $sData)
    $tCOPYDATA = DllStructCreate('dword;dword;ptr')
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    $Ret = DllCall('user32.dll', 'lparam', 'SendMessage', 'hwnd', $hWnd, 'int', $WM_COPYDATA, 'wparam', 0, 'lparam', DllStructGetPtr($tCOPYDATA))
    if (@error) or ($Ret[0] = -1) then
        return 0
    endif
    return 1
endfunc; _SendData
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
inververs [?]
Обнаружил что GUICtrlSendToDummy не будет работать, если окно скрыто(невидимо)
а какая нужда использовать именно такой способ передачи данных? есть ведь другие. и там не проблем с окном получателя (скрыто оно или нет)



Добавлено:
Сообщение автоматически объединено:

заметил глюк, что в таком виде коды если компилировать. то окно ресивера закрывается при посылке ему второго сообщения. при частых посылках сообщений текст сообщения теряет символы
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
joiner [?]
а какая нужда использовать именно такой способ передачи данных? есть ведь другие. и там не проблем с окном получателя (скрыто оно или нет)
других не видел которые можно приспособить для варианта Opt('GUIOnEventMode', 1)


заметил глюк, что в таком виде коды если компилировать. то окно ресивера закрывается при посылке ему второго сообщения. при частых посылках сообщений текст сообщения теряет символы
на 3.3.9.4 работает у меня нормально, ниодного вылета.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
да, на другой версии не закрывается.
но насчет

inververs [?]
это так обязательно в скрипте? а создать просто область данных, из которой они будут читаться другой программой?
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
joiner [?]
это так обязательно в скрипте?
да, это обязательно. т.к в скрипте GUI не является приоритетом, и служит лишь для отрисовки. Вся логика приложения довольно сложная и возврат в главный цикл, для прорисовки и реагирования на GUI не происходит.
А этот способ, нужен будет что бы вообще отделить графику от приложения. Так можно графику запускать отдельным EXE, а связь между ними через вот такие вот ON EVENT.



Добавлено:
Сообщение автоматически объединено:

Мне бы хотелось решить эту проблему.
Можно было бы подумать, как имитировать работу GUICtrlSendToDummy, но не понятно, как он работает, и что конкретно нужно отослать в этот Dummy что бы сработало для него GUICtrlSetOnEvent(DUMMY, "MAIN_DUMMY_EVENT")
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
inververs
извини, все равно туго понял твою идею.
разве так нельзя передавать данные? http://autoit-script.ru/index.php/topic,11757.msg77658.html#msg77658
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
joiner [?]
разве так нельзя?
вы в главном цикле вызываете что то, что бы узнать, пришли ли данные, в вашем примере это функция _Receiver(), и вызываете эту функцию постоянно лишь для этой проверки.
Получается что где-то в скрипте, нужно делать этот вызов. Но это не годится, если в скрипте много тяжелых внутренних циклов. Не будет же каждый раз туда вставлять _Receiver().
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
inververs
сделай так
Код:
Opt('GUIOnEventMode', 1)
Global Const $TITLE_RECEIVER = '#Reseiver'
Global Const $WM_COPYDATA = 0x004A
Global $hForm = GUICreate($TITLE_RECEIVER,0,0,10,10)
Global $DUMMY_MAIN = GUICtrlCreateDummy()
;GUICtrlSetOnEvent(-1, "MAIN_DUMMY_EVENT")
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
GUISetState(@SW_HIDE)
While 1
    Sleep(250)
WEnd
;Func MAIN_DUMMY_EVENT()

;EndFunc   ;==>MAIN_DUMMY_EVENT
Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
    Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
    Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
    $sMsg = DllStructGetData($tMsg, 1)
	If $sMsg <> '' Then
    GUICtrlSendToDummy($DUMMY_MAIN, $sMsg)
	MsgBox(0,'',GUICtrlRead($DUMMY_MAIN) & @LF)
	EndIf
EndFunc   ;==>_WM_COPYDATA

вроде как ты и хотел. окно скрыто

но теперь GUICtrlCreateDummy() уже не нужен :smile:
Код:
Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
    Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
    Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
    $sMsg = DllStructGetData($tMsg, 1)
	If $sMsg <> '' Then
    ;GUICtrlSendToDummy($DUMMY_MAIN, $sMsg)
	MsgBox(0,'',$sMsg & @LF)
	EndIf
EndFunc   ;==>_WM_COPYDATA
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
это все не то и не правильно.
_WM_COPYDATA должна выполняться быстро, ее задача только принять сообщение,
с нее нежелатьно вызывать даже функции, поэтому практика такая, что факт поступления сообщение передаются через GUICtrlSendToDummy, и дальше уже обрабатываются.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs

приёмник

Код:
HotKeySet("{ESC}", "_Exit")
Func _Exit()
    Exit
EndFunc
AdlibRegister('_Event', 100) ; 10 раз в секунду вроде достаточно

While 1
	Sleep(25000)
WEnd

Func _Event()
	Local $iState = RegRead('HKEY_CURRENT_USER\Software\temp', 'trigger') ; Чтение состояние триггера
	If @error Or Not $iState Then Return ; выпрыг, если не существует или равен 0
	$iState = RegRead('HKEY_CURRENT_USER\Software\temp', 'Data') ; Чтение данных
	If @error Then Return ; выпрыг, если не удалось
	RegWrite('HKEY_CURRENT_USER\Software\temp', 'trigger', 'REG_DWORD', 0) ; Сбрасывает триггер, сигнализируя о прочтении
	RegDelete('HKEY_CURRENT_USER\Software\temp', 'Data') ; Удаляет прочитанные данные
	ConsoleWrite($iState & @LF) ; Вывод в консоль
EndFunc   ;==>_Event


отправитель
Код:
RegWrite('HKEY_CURRENT_USER\Software\temp', 'trigger', 'REG_DWORD', 1) ; Установка триггера, сигнализируя о высылке данных
RegWrite('HKEY_CURRENT_USER\Software\temp', 'Data', 'REG_SZ', 'ТЕСТ') ; Высылка данных
Sleep(1000)
RegDelete('HKEY_CURRENT_USER\Software\temp') ; Удаляет временный раздел при завершении скрипта
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
inververs [?]
_WM_COPYDATA должна выполняться быстро, ее задача только принять сообщение,с нее нежелатьно вызывать даже функции, поэтому практика такая, что факт поступления сообщение передаются через GUICtrlSendToDummy, и дальше уже обрабатываются.
ну так ты вызываешь функцию
Код:
GUICtrlSendToDummy($DUMMY_MAIN, $sMsg)

а иначе зачем нужна _WM_COPYDATA. чтобы получить и отдать значение.
в отправщике ты используешь аpi функцию для передачи сообщения окну. потом идешь в обход - передаешь это сообщение элементу окна
Код:
GUICtrlCreateDummy()

это дольше, чем если бы _WM_COPYDATA получив напрямую реализовывала данные. к примеру запись в файл или еще что то
поэтому самый быстрый вариант ресивера исходя из предложенного тобой кода. но так или иначе все функции скрипт будет выполнять по очереди. как бы они не вызывались. это ограничение не обойдешь
Код:
Opt('GUIOnEventMode', 1)
Global Const $TITLE_RECEIVER = '#Reseiver'
Global Const $WM_COPYDATA = 0x004A
Global $hForm = GUICreate($TITLE_RECEIVER,0,0,10,10)
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
GUISetState(@SW_HIDE)
While 1
    Sleep(250)
WEnd

Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
    Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
    Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
    $sMsg = DllStructGetData($tMsg, 1)
	ConsoleWrite($sMsg & @LF); или функция или передача данных 
EndFunc   ;==>_WM_COPYDATA
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
AZJIO
преимущество GUICtrlSendToDummy в том, что ниодно из полученных сообщений не пропадает в случае невозможности их немедленной обработки. Т.к. создается очередь сообщений, которая затем будет обработатана.
Если же передатчик будет вписывать свои сообщения в переменную, в реестр, куда нибудь в другое место, то старые данные просто затирутся новыми.



Добавлено:
Сообщение автоматически объединено:

joiner
Обрабатывать сразу в _WM_COPYDATA тоже вариант, но в справке по GUIRegisterMsg написано:
Warning: blocking of running user functions which executes window messages with commands such as "Msgbox()" can lead to unexpected behavior, the return to the system should be as fast as possible !!!
и не факт, что я не захочу внутри _WM_COPYDATA вызывать msgbox.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
в данном конкретном случае происходит только передача данных. зачем здесь окно сообщений?

inververs [?]
и не факт, что я не захочу внутри _WM_COPYDATA вызывать msgbox.
ну тут хозяин - барин :smile:. если будет не критично, то можно.
на счет msgbox: если я использую его в функциях, то только перед выходом из функции.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Вот еще в подтверждении тому что вариант обработки всего в _WM_COPYDATA глючный.
Вот приемник, в котором мы принимаем сообщения, дальше их анализируем и выполняем определенные действия. Допустим в результате должна заработать функция go
Код:
Opt('GUIOnEventMode', 1)
Global Const $TITLE_RECEIVER = '#Reseiver'
Global Const $WM_COPYDATA = 0x004A
Global Const $WM_USER = 0x0400
Global $hForm = GUICreate($TITLE_RECEIVER,0,0,-1000,-1000)
Global $DUMMY_MAIN = GUICtrlCreateDummy()
GUICtrlSetOnEvent(-1, "MAIN_DUMMY_EVENT")
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')

GUISetState()

While 1
	Sleep(250)
WEnd

Func MAIN_DUMMY_EVENT()
	_go()
EndFunc   ;==>MAIN_DUMMY_EVENT

Func _go()
	Static $run = 1
	ConsoleWrite('gostart ' & $run & @LF)
	For $i = 1 To 10
		ConsoleWrite('.')
		Sleep(100)
	Next
	ConsoleWrite( @LF & 'goend ' & $run& @LF)
	$run+=1
EndFunc


Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
	Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
	Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
	$sMsg = DllStructGetData($tMsg, 1)
	;; Здесь мы проанализировали сообщение и так вышло, что нужно запскать функцию go, пропустим предварительный код запустим сразу
	_go()
EndFunc


Если теперь запустить передатчик, то видно будет что он зависнет пока наша функция ответсвенная за _WM_COPYDATA не закончит работу.

А теперь представь ситуацию, что источником сообщений является GUI окошко. Это же катастрофа, нажал на кнопку, и приложение зависло.. так дело не пойдет!

Другой вариант, если же _WM_COPYDATA сразу завершает работу, складирует все сообщения в очередь через GUICtrlSendToDummy.
Перепишем _WM_COPYDATA
Код:
Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
	Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
	Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
	$sMsg = DllStructGetData($tMsg, 1)
	;; Здесь мы проанализировали сообщение и так вышло, что нужно запскать функцию go, пропустим предварительный код запустим сразу
	GUICtrlSendToDummy($DUMMY_MAIN,$sMsg)
EndFunc


Теперь передатчик можно запустить несколько раз, и видно будет, что функция go выполниться столько раз, сколько пришло сообщений.



Добавлено:
Сообщение автоматически объединено:

:whistle: окно нельзя сделать невидимым, но можно его не показывать:
Код:
Global $hForm = GUICreate($TITLE_RECEIVER, 0, 0, -300, -300, -1, BitOR($WS_EX_TOOLWINDOW,$WS_EX_TRANSPARENT,$WS_EX_LAYERED))


теперь сообщения доходят, окна нет, все ок
Единственное, можно еще сделать что бы при запуске не отнимался фокус у приложения. Было бы круто! 8)
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
ну доходят сообщения. и что дальше? ведь ты будешь выполнять другие функции через
Код:
GUICtrlSetOnEvent(-1, "MAIN_DUMMY_EVENT")

а многопоточности нет.
я установил функцию копирования в MAIN_DUMMY_EVENT. виснет даже отправитель.. пока не скопируется файл..а он не маленький..
можно просто формировать массив и при выполнении очередного индекса массива удалять этот индекс.
и опять же не используя
Код:
GUICtrlSendToDummy

ну раз решил задачу. то можно не заморачиваться. всякое решение сугубо для конкретной ситуации.
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
inververs
Теоретически можно и в очередь писать через реестр, тут ведь как настроишь так и будет. Пишешь увеличивая счётчик номера записи в разделе реестра, приёмник считывает, удаляет, увеличивает свой синхронный счётчик ожидая запись под новым номером. Просто как я понял проблема GUI мешает, а тут и без GUI работает.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
joiner
ага, есть такое дело. Значит не судьба) И вообще, мне кажется что способ коммуникации через windows сообщения не очень надежный, т.к они где то теряются, и не всегда доходят.
Вот мой пример, по разделению кода и GUI

core:
Код:
Opt('GUIOnEventMode', 1)
Global Const $WM_COPYDATA = 0x004A
Global $GUI_WINDOW_ID = '#GUI'
Global $hWND_GUI = WinGetHandle($GUI_WINDOW_ID)
Global Enum $GUI_EVENT_NULL, $GUI_EVENT_GO, $GUI_EVENT_STOP
Global $GUI_LAST_EVENT = $GUI_EVENT_NULL

GUICreate('#Reseiver', 0, 0, -300, -300, -1, 0x800A0) ;BitOR($WS_EX_TOOLWINDOW,$WS_EX_TRANSPARENT,$WS_EX_LAYERED)
Global $DUMMY_CORE = GUICtrlCreateDummy()
GUICtrlSetOnEvent($DUMMY_CORE, "DUMMY_CORE")
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')
GUISetState()



Func _SendData($sData)
	Local $tCOPYDATA, $tMsg
	If IsHWnd($hWND_GUI) Then
		$tMsg = DllStructCreate('char[' & StringLen($sData) + 1 & ']')
		DllStructSetData($tMsg, 1, $sData)
		$tCOPYDATA = DllStructCreate('dword;dword;ptr')
		DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
		DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
		DllCall('user32.dll', 'lparam', 'SendMessage', 'hwnd', $hWND_GUI, 'int', $WM_COPYDATA, 'wparam', 0, 'lparam', DllStructGetPtr($tCOPYDATA))
	Else
		$hWND_GUI = WinGetHandle($GUI_WINDOW_ID)
	EndIf
EndFunc   ;==>_SendData

Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
	Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
	Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
	Local $sMsg = DllStructGetData($tMsg, 1)
	GUICtrlSendToDummy($DUMMY_CORE, $sMsg)
EndFunc   ;==>_WM_COPYDATA


Func DUMMY_CORE() ;Сообщения от GUI
	Switch GUICtrlRead($DUMMY_CORE)
		Case 'bye'
			Exit
		Case 'go_click'
			$GUI_LAST_EVENT = $GUI_EVENT_GO
		Case 'stop_click'
			$GUI_LAST_EVENT = $GUI_EVENT_STOP
	EndSwitch
EndFunc   ;==>DUMMY_CORE

_SendData('status:core on')

While 1
	If $GUI_LAST_EVENT Then
		Switch $GUI_LAST_EVENT
			Case $GUI_EVENT_NULL
			Case $GUI_EVENT_GO
				$GUI_LAST_EVENT = $GUI_EVENT_NULL
				_go()
			Case $GUI_EVENT_STOP
				$GUI_LAST_EVENT = $GUI_EVENT_NULL
				_SendData('status:stop')
		EndSwitch
	EndIf
	Sleep(100)
WEnd

Func _go()
	_SendData('status:working')
	For $i = 1 To 40
		If $GUI_LAST_EVENT = $GUI_EVENT_STOP Then Return ;Надо же выйти из цикла
		_SendData('state:' & $i)
		Sleep(10)
	Next
	_SendData('status:done')
EndFunc   ;==>_go


GUI
Код:
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Version=Beta
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
Opt('GUIOnEventMode', 1)

Global $GUI_WINDOW_ID = '#GUI'
Global $CORE_WINDOW_ID = '#Reseiver'
Global Const $WM_COPYDATA = 0x004A
Global $hWndCore = WinGetHandle($CORE_WINDOW_ID)

#region ### START Koda GUI section ### Form=
GUICreate($GUI_WINDOW_ID, 260, 72, 192, 161)
GUICtrlCreateLabel("Состояние:", 8, 16, 61, 17)
$Button1 = GUICtrlCreateButton("GO", 168, 8, 75, 25)
GUICtrlCreateLabel("Прогресс:", 8, 40, 56, 17)
$Button2 = GUICtrlCreateButton("STOP", 168, 32, 75, 25)
$Label3 = GUICtrlCreateLabel("core off", 80, 16, 68, 17)
$Label4 = GUICtrlCreateLabel("0", 80, 40, 68, 17)
GUISetState(@SW_SHOW)
#endregion ### END Koda GUI section ###

Global $DUMMY__GUI = GUICtrlCreateDummy()
GUISetOnEvent($GUI_EVENT_CLOSE, '_EXIT')
GUICtrlSetOnEvent($Button1, "GO_BUTTON")
GUICtrlSetOnEvent($Button2, "STOP_BUTTON")
GUICtrlSetOnEvent($DUMMY__GUI, "DUMMY__GUI")
GUIRegisterMsg($WM_COPYDATA, '_WM_COPYDATA')

Func _WM_COPYDATA($hWnd, $msgID, $wParam, $lParam)
	Local $tCOPYDATA = DllStructCreate('dword;dword;ptr', $lParam)
	Local $tMsg = DllStructCreate('char[' & DllStructGetData($tCOPYDATA, 2) & ']', DllStructGetData($tCOPYDATA, 3))
	Local $sMsg = DllStructGetData($tMsg, 1)
	GUICtrlSendToDummy($DUMMY__GUI, $sMsg)
EndFunc   ;==>_WM_COPYDATA

Func _SendData($sData)
	Local $tCOPYDATA, $tMsg
	If IsHWnd($hWndCore) Then
		$tMsg = DllStructCreate('char[' & StringLen($sData) + 1 & ']')
		DllStructSetData($tMsg, 1, $sData)
		$tCOPYDATA = DllStructCreate('dword;dword;ptr')
		DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
		DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
		DllCall('user32.dll', 'lparam', 'SendMessage', 'hwnd', $hWndCore, 'int', $WM_COPYDATA, 'wparam', 0, 'lparam', DllStructGetPtr($tCOPYDATA))
	Else
		$hWndCore = WinGetHandle($CORE_WINDOW_ID)
	EndIf
EndFunc   ;==>_SendData


Func DUMMY__GUI()
	Local $sData = GUICtrlRead($DUMMY__GUI)
	ConsoleWrite('> Пришло сообщение: ' & $sData & @LF)
	Local $aData = StringRegExp($sData, '[^:]+', 3)
	ReDim $aData[2]
	Switch $aData[0]
		Case 'status'
			GUICtrlSetData($Label3, $aData[1])
		Case 'state'
			GUICtrlSetData($Label4, $aData[1])
	EndSwitch
EndFunc   ;==>DUMMY__GUI

Func GO_BUTTON()
	_SendData('go_click')
EndFunc   ;==>GO_BUTTON

Func STOP_BUTTON()
	_SendData('stop_click')
EndFunc   ;==>STOP_BUTTON

Func _EXIT()
	Exit _SendData('bye')
EndFunc   ;==>_EXIT

While 1
	Sleep(250)
WEnd


Сообщения working всегда уходит из core но не всегда доходит до GUI

Печально вообщем, а был перспективный вариант...
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
в итоге GUI только мешает.все-таки стоит смотреть в сторону реализации без GUI
как и сказал
AZJIO [?]
Просто как я понял проблема GUI мешает, а тут и без GUI работает.
 
Автор
inververs

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Я хотел сделать GUI который не виснет. И отделить код от графики.
Отдельть код от графики получилось, даже не обязательно запускать его в отдельном скрипте, можно в том же, через include.

Был еще вариант слать через postmessage - что бы передатчик не зависал, но почему то тот-же _WM_COPYDATA не срабатывает.

Можно еще как вы и AZJIO подсказывали, хранить сообщение в третьем месте, используя счетчики, массивы итд, но это уже не касается темы :smile:
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
Приёмник
Код:
HotKeySet("{ESC}", "_Exit")
Func _Exit()
    Exit
EndFunc
Global $sTmpPath = 'HKEY_CURRENT_USER\Software\temp'
OnAutoItExitRegister('_OnExit') ; очищать будет приёмник
AdlibRegister('_Event', 200) ; 5 раз в секунду вроде достаточно

While 1
	Sleep(25000)
WEnd

Func _Event()
	Static $num = 1
	$vData = RegRead($sTmpPath, $num) ; Чтение данных
	If @error Then Return ; выпрыг, если не удалось
	RegDelete($sTmpPath, $num) ; Удаляет прочитанные данные
	$num += 1 ; увеличиваем счётчик
	ConsoleWrite($vData & @LF) ; Вывод в консоль
EndFunc   ;==>_Event

Func _OnExit()
	RegDelete($sTmpPath) ; Удаляет временный раздел при завершении скрипта
EndFunc   ;==>_Exit


Отправитель
Код:
; OnAutoItExitRegister('_Exit') ; очищать будет приёмник

; Высылка чисел
For $i = 1 To 10
	_RegSend(Random(10, 99, 1))
Next

; Высылка строк
For $i = 1 To 10
	$sString = ''
	For $j = 1 To Random(5, 20, 1)
		$sString &= Chr(Random(65, 90, 1)) ; Наполняем строку символами
	Next
	_RegSend($sString)
Next

; Высылка дробных чисел
For $i = 1 To 10
	_RegSend(Random())
Next

Func _RegSend($vData)
	Static $num = 0
	$num += 1
	Local $sType
	Switch VarGetType($vData)
		Case 'String'
			$sType = 'REG_SZ'
		Case 'Int32'
			$sType = 'REG_DWORD'
		Case 'Binary'
			$sType = 'REG_BINARY'
		Case 'Double'
			$sType = 'REG_SZ'
		Case Else
			$sType = 'REG_SZ'
	EndSwitch
	; MsgBox(0, 'Сообщение', $num &@LF&$sType &@LF&$vData)
	RegWrite('HKEY_CURRENT_USER\Software\temp', $num, $sType, $vData) ; Высылка данных
EndFunc   ;==>_RegSend

Func _Exit()
	RegDelete('HKEY_CURRENT_USER\Software\temp') ; Удаляет временный раздел при завершении скрипта
EndFunc   ;==>_Exit
 
Верх