1

Тема: AHK: Как передать данные из одного скрипта в другой?

Два работающих скрипта. В процессе работы первого, запускается второй скрипт (нужна именно параллельная работа). В результате работы второго скрипта получаем несколько переменных со значениями (например var1 = D, var2 = 1600). Как эту инфу передать первому скрипту?

На ум приходит только занести в clipboard, и то, типа как "D1600". А когда в первом скрипте понадобятся эти данные - проверить буфер обмена и развести опять на var1 = D, var2 = 1600.
Ну, или писать и читать из файлов. Что, наверное, еще сложнее.

Есть какие-нибудь более простые варианты передать данные? Извините, только начинаю изучать AHK

2

Re: AHK: Как передать данные из одного скрипта в другой?

Есть такой топик, например.
В последнем посте, если не ошибаюсь, teadrinker привел пример обмена сообщениями между скриптами посредством SendMessage.

3

Re: AHK: Как передать данные из одного скрипта в другой?

Наверное будет более наглядно для новичка.
Этим:


#SingleInstance Force
#Persistent    
#NoEnv
DetectHiddenWindows, On
PathScript = C:\Users\sergey\Desktop\=Test.ahk
Run %PathScript%,,,pid

Loop {
    Sleep 500
    Random, Rand, 56, 256
    Param := "var1=" Chr(Rand) Chr(Rand+115)
    SendMessage, 0xC, 0, &Param,, %PathScript% - AutoHotkey ahk_pid %pid%
    Param = var2=%Rand% 
    SendMessage, 0xC, 0, &Param,, %PathScript% - AutoHotkey ahk_pid %pid%
} 

Запукаете это:


#SingleInstance Force
#Persistent    
#NoEnv
OnMessage(0xC, "GetText")

GetText(wParam, lParam) { 
    Global  
    RegExMatch(StrGet(lParam), "(.*?)=(.*)", Data)
    %Data1% := Data2
    Return True 
}  
Loop
    MsgBox, , ,  % "var1 = " var1 "`n`nvar2 = " var2, 0.7
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

4

Re: AHK: Как передать данные из одного скрипта в другой?

А Вам же надо чтобы второй отправлял в первый, тогда ещё проще.

первый


#SingleInstance Force
#Persistent    
#NoEnv
OnMessage(0xC, "GetText")
Run C:\Users\sergey\Desktop\=Test.ahk %A_ScriptHwnd% 

Loop
    MsgBox, , , % "var1 = " var1 "`n`nvar2 = " var2, 0.7
    
GetText(wParam, lParam) { 
    Global  
    RegExMatch(StrGet(lParam), "(.*?)=(.*)", Data)
    %Data1% := Data2
    Return True 
}  

второй


#SingleInstance Force
#Persistent    
#NoEnv
DetectHiddenWindows, On
ScriptHwnd = %1%
Sleep 1500

Loop 
{
    Sleep 500
    Random, Rand, 0x0410, 0x042c
    Param := "var1=" Chr(Rand) Chr(Rand+1)
    SendMessage, 0xC, 0, &Param,, ahk_id %ScriptHwnd%
    Param = var2=%Rand% 
    SendMessage, 0xC, 0, &Param,, ahk_id %ScriptHwnd%
} 
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

5

Re: AHK: Как передать данные из одного скрипта в другой?

В вышеуказанном топике я писал, что использование WM_SETTEXT (0xC) ненадёжно, для отправки строки лучше использовать WM_COPYDATA.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6 (изменено: serzh82saratov, 2014-05-04 02:07:44)

Re: AHK: Как передать данные из одного скрипта в другой?

Насчёт WM_SETTEX,  я не замечал используя всегда только A_ScriptHWND. Ведь под ПИД подходят несколько окон скрипта, потому могут происходить промашки. Ниже приведённый код можно использовать как универсальный вариант для нескольких скриптов. Просто в MyNum указать номер этого скрипта, и в SendData() номер кому посылать. При запуске все скрипты обмениваются между собой своими A_ScriptHWND. Также при закрытии любого из них, остальные сразу закрываются.

+ открыть спойлер

DetectHiddenWindows, On
Global MyNum := 1 , arrID := {}
    , WM_MYMESSAGE := DllCall("RegisterWindowMessage", "Str", "WM_MYMESSAGE")
OnMessage(WM_MYMESSAGE, "WM_MYMESSAGE") 
OnMessage(0x4A, "WM_COPYDATA")
OnExit, Exit  
Sleep 100
SendMessage, WM_MYMESSAGE, MyNum, A_ScriptHWND,, ahk_id 0xFFFF 
return
 
1:: SendData("ТЕКСТ", 2) 
 
WM_COPYDATA(wp, lp)  {  
    ToolTip % "Это скрипт номер: " MyNum 
            . "`nПринял данные от скрипта номер: " wp "`n`n" 
            . StrGet(NumGet(lp + A_PtrSize*2))  
    return true
}

WM_MYMESSAGE(wp, lp)  {  
    If (wp = 256 && lp = 0)
        ExitApp 
    If (wp != MyNum && lp != A_ScriptHWND)
        arrID[wp] := lp 
    return true
} 
 
SendData(text, num)  {
    VarSetCapacity(COPYDATASTRUCT, A_PtrSize*3)
    DataSize := (StrLen(text) + 1)*(A_IsUnicode ? 2 : 1)
    NumPut(DataSize, COPYDATASTRUCT, A_PtrSize, "UInt")
    NumPut(&text, COPYDATASTRUCT, A_PtrSize*2) 
    SendMessage, 0x4A, MyNum, &COPYDATASTRUCT, , % "ahk_id" arrID[num]  
}
 
Exit:
    PostMessage, WM_MYMESSAGE, 256, 0, , ahk_id 0xFFFF
    ExitApp

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

7

Re: AHK: Как передать данные из одного скрипта в другой?

serzh82saratov пишет:

Ведь под ПИД подходят несколько окон скрипта, потому могут происходить промашки.

Для OnMessage() не важно, какому окну скрипта пришло сообщение.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

8

Re: AHK: Как передать данные из одного скрипта в другой?

Это то понятно, но сообщение переданное в главное окно, гарантированно не изменит заголовок.

WM_SETTEXT работает не совсем надёжно, т. к. это сообщение иногда проскакивает мимо OnMessage() и в таком случае обрабатывается окном, что приводит к смене заголовка на присланный текст.

Возможно проскакивание мимо, обусловлено наличием ещё одного подходящего окна?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

9

Re: AHK: Как передать данные из одного скрипта в другой?

Это то понятно, но сообщение переданное в главное окно, гарантированно не изменит заголовок.

Почему, оно может изменить заголовок главного окна. И в этом случае не сработает, как надо.

Возможно проскакивание мимо, обусловлено наличием ещё одного подходящего окна?

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

10

Re: AHK: Как передать данные из одного скрипта в другой?

Не думаю, используется первое найденное, подходящее под параметры

А где написано, что главное окно всегда первое найденное, я не нашёл.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

11

Re: AHK: Как передать данные из одного скрипта в другой?

В смысле? А откуда вообще ты это взял? Если у скрипта есть видимое окно, то по заголовку через ahk_pid первым найденным будет оно.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

12

Re: AHK: Как передать данные из одного скрипта в другой?

Если OnMessage не ловит сообщение, так это же баг. Сообщать надо разработчикам.

13

Re: AHK: Как передать данные из одного скрипта в другой?

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

14

Re: AHK: Как передать данные из одного скрипта в другой?

От 5 до 15 нажатий требуется, чтобы проявилось. Лучше бы пример попроще, конечно. В справке пишут, что сообщения с кодом меньше 0x312 могут пропускаться при некоторых условиях, так что уже поэтому не абсолютно надёжно. Но, кстати, код WM_COPYDATA тоже меньше 0x312.

15

Re: AHK: Как передать данные из одного скрипта в другой?

YMP пишет:

Лучше бы пример попроще, конечно.

Ситуацию не удалось смоделировать ни так:

Gui, Font, s18
Gui, Add, Text, vText x0 y0 w200 h30 Center
Gui, Show, w200 h30, Заголовок
PID := DllCall("GetCurrentProcessId")
OnMessage(0xC, "WM_SETTEXT")

Loop
{
   SendMessage, 0xC,, "Text " . A_Index,, ahk_pid %PID%
   Sleep, 100
}

WM_SETTEXT(wp, lp)
{
   GuiControl,, Text, % StrGet(lp)
   Return 0
}

GuiClose:
   ExitApp

ни так:

Gui, Font, s18
Gui, Add, Text, vText x0 y0 w200 h30 Center
Gui, Show, w200 h30, Заголовок
ParentPID := DllCall("GetCurrentProcessId")
OnMessage(0xC, "WM_SETTEXT")
OnExit, Exit

Script =
(
   #NoTrayIcon
   Loop
   {
      SendMessage, 0xC,, "Text " . A_Index,, ahk_pid %ParentPID%
      Sleep, 100
   }
)

FilePath := A_Temp "\_MyScript_" A_TickCount ".ahk"
FileAppend, % Script, % FilePath
Run, % FilePath,,, PID
DetectHiddenWindows, On
WinWait, % "ahk_pid" PID
FileDelete, % FilePath
Return

GuiClose:
   ExitApp

Exit:
   Process, Close, %PID%
   ExitApp

WM_SETTEXT(wp, lp)
{
   GuiControl,, Text, % StrGet(lp)
   Return 0
}

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Как передать данные из одного скрипта в другой?

teadrinker пишет:

Проконтролировать удачу или неудачу можно, проверяя код возврата.

Да, это плюс, конечно.

17

Re: AHK: Как передать данные из одного скрипта в другой?

Странно, что пример из справки у меня не работает.
http://www.autohotkey.com/docs/commands/OnMessage.htm
Пишет, что "%A_ScriptName%`nA blank string was received or there was an error."
Receiver.ahk

#SingleInstance
OnMessage(0x4a, "Receive_WM_COPYDATA")  ; 0x4a is WM_COPYDATA
return

Receive_WM_COPYDATA(wParam, lParam)
{
    StringAddress := NumGet(lParam + 8)  ; lParam+8 is the address of CopyDataStruct's lpData member.
    StringLength := DllCall("lstrlen", UInt, StringAddress)
    if StringLength <= 0
        ToolTip %A_ScriptName%`nA blank string was received or there was an error.
    else
    {
        VarSetCapacity(CopyOfData, StringLength)
        DllCall("lstrcpy", "str", CopyOfData, "uint", StringAddress)  ; Copy the string out of the structure.
        ; Show it with ToolTip vs. MsgBox so we can return in a timely fashion:
        ToolTip %A_ScriptName%`nReceived the following string:`n%CopyOfData%
    }
    return true  ; Returning 1 (true) is the traditional way to acknowledge this message.
}

Sender.ahk

TargetScriptTitle = Receiver.ahk ahk_class AutoHotkey

#space::  ; Win+Space hotkey. Press it to show an InputBox for entry of a message string.
InputBox, StringToSend, Send text via WM_COPYDATA, Enter some text to Send:
if ErrorLevel  ; User pressed the Cancel button.
    return
result := Send_WM_COPYDATA(StringToSend, TargetScriptTitle)
if result = FAIL
    MsgBox SendMessage failed. Does the following WinTitle exist?:`n%TargetScriptTitle%
else if result = 0
    MsgBox Message sent but the target window responded with 0, which may mean it ignored it.
return

Send_WM_COPYDATA(ByRef StringToSend, ByRef TargetScriptTitle)  ; ByRef saves a little memory in this case.
; This function sends the specified string to the specified window and returns the reply.
; The reply is 1 if the target window processed the message, or 0 if it ignored it.
{
    VarSetCapacity(CopyDataStruct, 12, 0)  ; Set up the structure's memory area.
    ; First set the structure's cbData member to the size of the string, including its zero terminator:
    NumPut(StrLen(StringToSend) + 1, CopyDataStruct, 4)  ; OS requires that this be done.
    NumPut(&StringToSend, CopyDataStruct, 8)  ; Set lpData to point to the string itself.
    Prev_DetectHiddenWindows := A_DetectHiddenWindows
    Prev_TitleMatchMode := A_TitleMatchMode
    DetectHiddenWindows On
    SetTitleMatchMode 2
    SendMessage, 0x4a, 0, &CopyDataStruct,, %TargetScriptTitle%  ; 0x4a is WM_COPYDATA. Must use Send not Post.
    DetectHiddenWindows %Prev_DetectHiddenWindows%  ; Restore original setting for the caller.
    SetTitleMatchMode %Prev_TitleMatchMode%         ; Same.
    return ErrorLevel  ; Return SendMessage's reply back to our caller.
}

И как это понять?

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

То есть существует вероятность, что информация не передастся?

18

Re: AHK: Как передать данные из одного скрипта в другой?

Malcev пишет:

Странно, что пример из справки у меня не работает.

Если мой пример с WM_COPYDATA работает, значит всё в порядке.

То есть существует вероятность, что информация не передастся?

Существует, читай General Remarks.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

19

Re: AHK: Как передать данные из одного скрипта в другой?

Всё таки повторюсь, но не пойму я всей кучи заморочек связанной с такими передачами.
В таких "многопоточных" вариантах, скрипты лежат в одной папке. Чем не проще использовать ини файл? Запустили приёмник, записали A_ScriptHwnd. Запустили отправителя. Надо оповестить, записали в ини инфу, прочитали A_ScriptHwnd, отправили DllCall("RegisterWindowMessage", "Str", "MyMessage") для A_ScriptHwnd приёмника сообщение о необходимости прочтения инфы.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

20

Re: AHK: Как передать данные из одного скрипта в другой?

А можно пример такой взаимосвязи?
Понял почему пример с оффсайта не работает.
Потому что он лежит http://www.autohotkey.com/docs/commands/OnMessage.htm
А надо использовать http://ahkscript.org/docs/commands/OnMessage.htm
Только народ путают!!!

21

Re: AHK: Как передать данные из одного скрипта в другой?

serzh82saratov пишет:

Чем не проще использовать ини файл?

Не совсем понял твою мысль. Ты предлагаешь алгоритм в три шага вместо одного?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

22

Re: AHK: Как передать данные из одного скрипта в другой?

Malcev пишет:

Понял почему пример с оффсайта не работает.
Потому что он лежит http://www.autohotkey.com/docs/commands/OnMessage.htm
А надо использовать http://ahkscript.org/docs/commands/OnMessage.htm

Да, на http://www.autohotkey.com/docs/commands/OnMessage.htm — под AHK-basic.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

23

Re: AHK: Как передать данные из одного скрипта в другой?

teadrinker пишет:

Ты предлагаешь алгоритм в три шага вместо одного?

Смотря что считать шагами. А то можно например и в Send_WM_COPYDATA каждую строку посчитать за шаг.  И в чём "однократность шага" выше предложенного.

Malcev пишет:

А можно пример такой взаимосвязи?

Да вроде всё совсем просто.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

24

Re: AHK: Как передать данные из одного скрипта в другой?

Ну вот смотри, в моём варианте, чтобы передать строку текста нужно создать структуру

VarSetCapacity(COPYDATASTRUCT, A_PtrSize*3)
DataSize := (StrLen(string) + 1)*(A_IsUnicode ? 2 : 1)
NumPut(DataSize, COPYDATASTRUCT, A_PtrSize, "UInt")
NumPut(&Edit1, COPYDATASTRUCT, A_PtrSize*2)

и отправить сообщение. В скрипте-приёмнике соответственно принять и прочитать строку с помощью StrGet().

Ты же предлагаешь записать строку в ini, зарегистрировать сообщение, отправить его, в приёмнике принять, затем прочитать строку из ini. В чём выгода?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

25 (изменено: serzh82saratov, 2014-06-25 21:49:50)

Re: AHK: Как передать данные из одного скрипта в другой?

Ну вот смотри, в моём варианте,

Ещё отправить PID, и прочитать его.

В чём выгода?

Думаю - в простоте. Пара строк IniRead, IniWrite выглядят проще.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

26

Re: AHK: Как передать данные из одного скрипта в другой?

serzh82saratov пишет:

Ещё отправить PID, и прочитать его.

Если это дочерний скрипт, то PID передаётся при его создании через переменную.

Думаю - в простоте.

Зато очевидный проигрыш в скорости.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

27

Re: AHK: Как передать данные из одного скрипта в другой?

А с точки зрения надежности какой вариант лучше?

28

Re: AHK: Как передать данные из одного скрипта в другой?

Зато очевидный проигрыш в скорости.

Сомневаюсь что для кого то это может быть критичным.
Я ведь предложил не как единственно правильный вариант, а для простоты понимания новичками.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

29

Re: AHK: Как передать данные из одного скрипта в другой?

serzh82saratov пишет:

Сомневаюсь что для кого то это может быть критичным.

В смысле, "для кого-то"? По-моему, это от задачи зависит.

для простоты понимания новичками.

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

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

30

Re: AHK: Как передать данные из одного скрипта в другой?

Malcev пишет:

А с точки зрения надежности какой вариант лучше?

Смотря, как всё обустроить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

31

Re: AHK: Как передать данные из одного скрипта в другой?

Как я понимаю, надо каким-то образом Сендеру ждать ответа от ресивера о получении либо неполучении сообщения.
А как  такое осуществить не пойму.

32

Re: AHK: Как передать данные из одного скрипта в другой?

В OnMessage() ресивера возвращать 1, в сендере после отправки проверять ErrorLevel.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

33

Re: AHK: Как передать данные из одного скрипта в другой?

В смысле, "для кого-то"? По-моему, это от задачи зависит.

Так я и говорю, как вариант.

сообщение регистрировать

Оно не сложно, да и можно от балды написать нечто вроде 0х555.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru Telegram: https://t.me/sergiol982
Win10x64 AhkSpy, Hotkey, ClockGui

34

Re: AHK: Как передать данные из одного скрипта в другой?

Ну, от балды-то можно много чего написать, вопрос зачем.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

35

Re: AHK: Как передать данные из одного скрипта в другой?

Совсем уж от балды сообщения брать нежелательно. Разные их диапазоны для разного предназначены. Вот тут они перечислены, например: http://msdn.microsoft.com/en-us/library … s.85).aspx.