Triggering a subroutine from another script

Get help with using AutoHotkey and its commands and hotkeys
Zvonko
Posts: 210
Joined: 19 Jun 2015, 11:52

Triggering a subroutine from another script

26 Jul 2016, 03:44

The only way I discovered so far to trigger a subroutine defined in an ahk script from another ahk script is demonstrated below: By associating a hotkey to the subroutine and using the Send command (F8::) to trigger this hotkey from another script.

Code: Select all

;Gui Add, Button, gSubRoutine, Button	; With this line, 'Send msg{Space}' in 'F6::' works!!!
Gui Show, x100 y100 w100 h100
return

SubRoutine:
!^+m::
::msg::
MsgBox This is a MsgBox.
return

F8::				; Is intended to be defined in another script!
Send !^+m			; Triggering a hotkey.
return

F7::				; Is intended to be defined in another script!
SendLevel 1
Send msg{Space}		; Triggering a hotstring.*
SendLevel 0
return

F6::				; Is intended to be defined in another script!
Send msg{Space}		; Triggering a hotstring.*
return


GuiClose:
ExitApp
return

; * HotString Help: By default, hotstrings are never triggered by keystrokes produced by any AutoHotkey script.
; ...this behaviour can be controlled with #InputLevel and SendLevel.
This works fine! My first and main question:
Are there other (better) methods?

With a small adaptation (SendLevel, F7::) also hotstrings can be used. My second question is a newbie understanding issue: If the first line is included in the demo script, the subroutine is triggered by Send & hotstring (F6::) without 'SendLevel 1', or even with 'SendLevel 0'!!! Why?
For me as a newbie it is frustrating to fail due to "little" problems in projects in which the entire concept and even complex functions are working perfectly...
Zvonko
Posts: 210
Joined: 19 Jun 2015, 11:52

Re: Triggering a subroutine from another script

26 Jul 2016, 05:32

I see, boiler, thank you very much. However, this seems to be a method suitable for more general and complex use, for my simple purpose the hotkey/hotstring method is much more simpler and transparent (for a newbie).
For me as a newbie it is frustrating to fail due to "little" problems in projects in which the entire concept and even complex functions are working perfectly...
Zvonko
Posts: 210
Joined: 19 Jun 2015, 11:52

Re: Triggering a subroutine from another script

26 Jul 2016, 06:44

Thank you, Guest, another interesting method for more general and complex use.

At the moment I prefer the hotstring/hotkey method because of its simplicity. Hotstring is even better than hotkey: When defining a hotkey for this purpose the risk of conflicts with already used hotkeys is to be considered, and the hotkeys are limited and restricted to the keyboard layout of the user's PC (which may be unknown!); with hotstrings like @1¥ there are no such risks and problems. EDITED: Not correct, the keyboard layout restriction is valid for hotstrings too. Such hotstrings seems to work with Win10, but not with WinXP! The documentation says: "Any character which does not correspond to a key in the current keyboard layout cannot trigger a hotstring, even if SendLevel is used. This is a limitation of the hotstring recognizer." (But the hotstring method is still better to avoid conflicts.)

'Master' script:

Code: Select all

; 'Master' script:

SubRoutine:
::@1¥::				; HOTSTRING SOLUTION for triggering the subroutine from other ('slave') scripts!
MsgBox This is a MsgBox.
return
'Slave' script:

Code: Select all

; 'Slave' script:

F7::	
SendLevel 1			; HOTSTRING SOLUTION!
Send @1¥{Space}		; Triggering the hotstring defined in the subroutine-containing ('master') script!
SendLevel 0
return
Last edited by Zvonko on 01 Sep 2016, 09:42, edited 5 times in total.
For me as a newbie it is frustrating to fail due to "little" problems in projects in which the entire concept and even complex functions are working perfectly...
wolf_II
Posts: 2688
Joined: 08 Feb 2015, 20:55

Re: Triggering a subroutine from another script

26 Jul 2016, 07:19

You could also try this less complex approach:

Master.ahk

Code: Select all

;-------------------------------------------------------------------------------
; Master.ahk
;-------------------------------------------------------------------------------
    #SingleInstance, Ignore
    OnMessage(0x4a,"receive_WM_COPYDATA")

Return

Remote_Exit:
ExitApp

RemoteControl_01:
RemoteControl_02:
RemoteControl_03:
    MsgBox,,, This is %A_ThisLabel%, 2
Return


;-------------------------------------------------------------------------------
receive_WM_COPYDATA(wParam, lParam) { ; launch a label
;-------------------------------------------------------------------------------
    DATA := StrGet(NumGet(lParam+A_PtrSize*2),(NumGet(lParam+A_PtrSize)-1)/2)
    If IsLabel(DATA)
        Gosub, %DATA%
    Return, 0
}
Slave.ahk

Code: Select all

;-------------------------------------------------------------------------------
; Slave.ahk
;-------------------------------------------------------------------------------
    send_DATA("RemoteControl_01", "Master.ahk") ; launch a label in Master.ahk
    send_DATA("RemoteControl_02", "Master.ahk") ; launch a label in Master.ahk
    send_DATA("RemoteControl_03", "Master.ahk") ; launch a label in Master.ahk
    send_DATA("Remote_Exit",      "Master.ahk") ; launch a label in Master.ahk

ExitApp



;-------------------------------------------------------------------------------
send_DATA(DATA, Receiver) { ; using WM_COPYDATA message
;-------------------------------------------------------------------------------
    If Not UniqueID := WinExist(Receiver) {
        SetTitleMatchMode, 2
        DetectHiddenWindows, On
        Run, %Receiver%
        WinWait, %Receiver% - AutoHotkey
    }

    ; send WM_COPYDATA message to Receiver
    VarSetCapacity(COPYDATASTRUCT,A_PtrSize*3,0)
    NumPut(StrLen(DATA)*2+1,COPYDATASTRUCT,A_PtrSize,"UInt")
    NumPut(&DATA,COPYDATASTRUCT,A_PtrSize*2,"UInt")
    SendMessage,0x4a,,&COPYDATASTRUCT,,%Receiver%
}
SvenBent
Posts: 266
Joined: 09 Aug 2015, 01:34

Re: Triggering a subroutine from another script

26 Jul 2016, 09:12

Can use a run command too i you want to
Zvonko
Posts: 210
Joined: 19 Jun 2015, 11:52

Re: Triggering a subroutine from another script

26 Jul 2016, 09:21

@SvenBent:
To run a subroutine from another script? Can you show an example?
For me as a newbie it is frustrating to fail due to "little" problems in projects in which the entire concept and even complex functions are working perfectly...
Zvonko
Posts: 210
Joined: 19 Jun 2015, 11:52

Re: Triggering a subroutine from another script

28 Jul 2016, 05:39

I would like to reactivate this question, but now limited to the following script which uses the hotstring method.* EDIT: See next posting for a new variant.

I was forced to provide an auxiliary gui used only for the Send command, to avoid undesired side effects of Send & hotstring in other windows. This works fine, but there are maybe more clever solutions for this problem, and maybe for other details of the hotstring method too. All hints are welcome.

Code: Select all

; ----------------------------------------------------------------------------------------------------------
; Master script
; ----------------------------------------------------------------------------------------------------------

:*b0:¥1¥::								; A unique hotstring associated to the subroutine to be used
SubRoutine:								; for triggering the subroutine from a slave script.
   MsgBox This is a MsgBox.				; (Asterix: No ending character needed. b0: No backspacing.)
return

; ----------------------------------------------------------------------------------------------------------
; Slave script
; ----------------------------------------------------------------------------------------------------------

Gui Dump: +Owner						; Just to have a gui where the hotstring fizzles out.
Gui Dump: Show, , DumpGui				; (+Owner: No taskbar button.)

RETURN

F7::									; Triggering the subroutine defined in the master script.
   WinGet, CurrActWin, ID, A			; Determining active window,
   WinActivate, DumpGui					; activating the DumpGui.
   SendLevel 1							; Enabling Send to trigger a hotstring.
   SendInput ¥1¥						; SendInput: Faster than Send.
   WinActivate, ahk_id %CurrActWin%		; Reactivating the window.
return

* As already said above, I prefer this solution to the hotkey method. (When defining a hotkey for this purpose the risk of conflicts with already used hotkeys is to be considered, and the hotkeys are limited and restricted to the keyboard layout of the user's PC (which may be unknown!); with hotstrings like @1¥ there are no such risks and problems.) EDITED: Not correct, the keyboard layout restriction is valid for hotstrings too. Such hotstrings seems to work with Win10, but not with WinXP! The documentation says: "Any character which does not correspond to a key in the current keyboard layout cannot trigger a hotstring, even if SendLevel is used. This is a limitation of the hotstring recognizer." (But the hotstring method is still better to avoid conflicts.)
Last edited by Zvonko on 01 Sep 2016, 09:41, edited 2 times in total.
For me as a newbie it is frustrating to fail due to "little" problems in projects in which the entire concept and even complex functions are working perfectly...
Zvonko
Posts: 210
Joined: 19 Jun 2015, 11:52

Re: Triggering a subroutine from another script

29 Jul 2016, 04:16

A new variant.
(No hints? Is this approach too trivial?)

Code: Select all

; Master script ------------------------------------------------------------------------------------------

:*b0:¥Subroutine¥::								; A unique hotstring associated to the subroutine to be used
Subroutine:										; for triggering the subroutine from a slave script.
   MsgBox This is a MsgBox from master script.
return

; Slave script ------------------------------------------------------------------------------------------

F7:: RunMasterSubroutine("¥Subroutine¥")		; Triggering the hotstring & subroutine defined in the master script.

RunMasterSubroutine(hs)
{
   Gui Dump: +Owner
   Gui Dump: Show
   SendLevel 1	
   SendInput %hs%
   Gui Dump: Destroy
}
For me as a newbie it is frustrating to fail due to "little" problems in projects in which the entire concept and even complex functions are working perfectly...

Return to “Ask For Help”

Who is online

Users browsing this forum: anhnha, casperharkin, Chunjee, Google [Bot], littlegandhi1199, sobuj53, VibinonAHk, Xeo786 and 42 guests