About AhkThread (Parent, Child and Sibling)

Ask for help, how to use AHK_H, etc.
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 00:20

Hello,

Sorry for not translating my study into English, I believe you all can understand. My question is about changing variables between child threads, in the example below everything works, but when I try to get the sibling variable it is not catching, can someone help me sort it out, please !?

Code: Select all

#NoEnv
#NoTrayIcon
#SingleInstance, Force

Gui, Add, Button, h50 w200 vIrmao1 gIrmao1G, LIGAR IRMÃO 1
Gui, Add, Button, h50 w200 vIrmao2 gIrmao2G, LIGAR IRMÃO 2
Gui, Add, Button, h50 w200 gPaiGResetarFilho1, PARAR FILHO 1
Gui, Add, Button, h50 w200 gPaiGResetarFilho2, PARAR FILHO 2
Gui, Show, `t
return

; PAI LÊ VARIAVEL DOS FILHOS
;============================================
PaiGResetarFilho1:
    ContadorFilho1 = Irmao01Thread.AhkGetVar.ContadorFilho1 ; pega variável de alguma thread
    Irmao01Thread.AhkExec("MsgBox % ""PAI MANDOU EU (FILHO 1) PARAR DE CONTAR E FALAR ISSO!``nFILHO 1 PAROU DE CONTAR EM "" ContadorFilho1") ; executa esse comando em alguma thread externa a essa
    Filho2FicaSabendo = 1
    Sleep, 100
    Filho2FicaSabendo = 0
return

PaiGResetarFilho2:
    ContadorFilho2 = Irmao02Thread.AhkGetVar.ContadorFilho2 ; pega variável de alguma thread
    Irmao02Thread.AhkExec("MsgBox % ""PAI MANDOU EU (FILHO 2) PARAR DE CONTAR E FALAR ISSO!``nFILHO 2 PAROU DE CONTAR EM "" ContadorFilho2") ; executa esse comando em alguma thread externa a essa
    Filho1FicaSabendo = 1
    Sleep, 100
    Filho1FicaSabendo = 0
return

; THREADS DOS FILHOS
;============================================
toggleIrmao1 := 0
Irmao1G:
    toggleIrmao1 := !toggleIrmao1
    if (toggleIrmao1) {
        GuiControl,, Irmao1, DESLIGAR IRMÃO 1
        Irmao01Script := CriticalObject()
        script:="                    
        ("    
            #NoEnv
            #NoTrayIcon
            Loop
            {
                ContadorFilho1 = %A_Index%
                ToolTip, FILHO 1 ESTÁ CONTANDO: %ContadorFilho1%, 250, -50
                PaiThread := AhkExported() ; pega variáveis do pai e vincula com o AhkGetVar para lançar dentro da thread
                Filho1FicaSabendo := PaiThread.AhkGetVar.Filho1FicaSabendo ; nesse caso, está pegando a variável que veio do pai para lançar dentro dessa thread
                if (Filho1FicaSabendo) {
                    MsgBox % ""FILHO 1 FICOU SABENDO QUE PAI PAROU SEU IRMÃO (FILHO 2)``nO FOFOQUEIRO TAMBÉM PAROU DE CONTAR EM: "" ContadorFilho1
                    PaiThread.AhkExec(""MsgBox % """"PAI FICA PUTO E MANDA ESSA MENSAGEM PQ VIU QUE O FILHO2 PAROU EM: """" ""ContadorFilho1) ; executa esse comando em alguma thread externa a essa
                }
            }
        )"
        Irmao01Thread:=AhkThread(script,&Irmao01Script)
    } else {
        Irmao01Thread.ahkTerminate()
        GuiControl,, Irmao1, LIGAR IRMÃO 1
    }
return

;  IDK IF THAT IS CORRECT
; =========================================================
Irmao01Thread.AhkAssign("Irmao02ThreadPtr", &Irmao02Thread "")
; =========================================================
;  IDK IF THAT IS CORRECT

toggleIrmao2 := 0 
Irmao2G: 
    toggleIrmao2 := !toggleIrmao2
    if (toggleIrmao2) {
        GuiControl,, Irmao2, DESLIGAR IRMÃO 2 
        Irmao02Script := CriticalObject()
        script:="                        
        ("     
            #NoEnv 
            #NoTrayIcon
            Loop
            {
                ContadorFilho2 = %A_Index%
                ToolTip, FILHO 2 ESTÁ CONTANDO: %ContadorFilho2%, 250, -30
                PaiThread := AhkExported() ; pega variáveis do pai e vincula com o AhkGetVar para lançar dentro da thread
                Filho2FicaSabendo := PaiThread.AhkGetVar.Filho2FicaSabendo ; nesse caso, está pegando a variável que veio do pai para lançar dentro dessa thread
                if (Filho2FicaSabendo) {
                
                    ;  MY PROBLEM IS HERE - ContadorFilho1 DONT GET
                    ; ==============================================================================
                    Irmao02Thread := Object(Irmao02ThreadPtr) ; OU USE criticalobject()
                    ContadorFilho1 := Irmao02Thread.AhkGetVar.ContadorFilho1
                    MsgBox % ""FILHO 2 VIU QUE IRMÃO 1 PAROU DE CONTAR EM: "" ContadorFilho1
                    ; ==============================================================================
                    ;  MY PROBLEM IS HERE - ContadorFilho1 DONT GET
                                        
                    MsgBox % ""FILHO 2 FICOU SABENDO QUE PAI PAROU SEU IRMÃO (FILHO 1)``nO FOFOQUEIRO TAMBÉM PAROU DE CONTAR EM: "" ContadorFilho2
                    
                    PaiThread.AhkExec(""MsgBox % """"PAI FICA PUTO E MANDA ESSA MENSAGEM PQ VIU QUE O FILHO2 PAROU EM: """" ""ContadorFilho2) ; executa esse comando em alguma thread externa a essa
                }
            }
        )"
        Irmao02Thread:=AhkThread(script,&Irmao02Script)
    } else {
        Irmao02Thread.ahkTerminate()
        GuiControl,, Irmao2, LIGAR IRMÃO 2
    }
return

GuiClose:
ExitApp
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 15:58

Try Irmao01Thread.AhkAssign("Irmao02ThreadPtr", (&Irmao02Thread) "")
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 16:42

HotKeyIt wrote:
10 Jul 2019, 15:58
Try Irmao01Thread.AhkAssign("Irmao02ThreadPtr", (&Irmao02Thread) "")
Thank you to try help, my friend, but the problem continues... :cry:
Screenshot_1.png
Screenshot_1.png (47.98 KiB) Viewed 5136 times
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 16:47

Can you put a very simple script together doing the same?
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 16:54

HotKeyIt wrote:
10 Jul 2019, 16:47
Can you put a very simple script together doing the same?
Yes, just a min.. pls
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 17:05

u have bits of unreachable code, shoved in between labels and return statements
u believe we can all understand, but im not so sure, this all looks like complete gibberish to me. i dont understand what ure trying to do.
ure trying to, within thread2, obtain a ptr to thread2(a ptr, which u havent made available in any way), and then ure trying to fetch thread2's contradorfihlo1(a variable which was never assigned in thread2) ??
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 17:16

@HotKeyIt

Code: Select all

#NoEnv
#NoTrayIcon
#SingleInstance, Force

Gui, Add, Checkbox, h50 w400 vSIBLING1 gSIBLING1G, CHECK TO START COUNT WITH SIBLING 1
Gui, Add, Button, h50 w400 vSIBLING2 gSIBLING2G, CHECK WITH SIBLING 2
Gui, Show, `t
return

;SIBLING1
;===============
toggleSIBLING1 := 0
SIBLING1G:
    toggleSIBLING1 := !toggleSIBLING1
    if (toggleSIBLING1) {
        SIBLING1Script := CriticalObject()
        script:="                     
        ("     
            #NoEnv
            #NoTrayIcon
            Loop
            {
                SIBLING1Count = %A_Index%
                ToolTip, Sibling count: %SIBLING1Count%
            }
        )"
        SIBLING1Thread:=AhkThread(script,&SIBLING1Script)
    } else {
        SIBLING1Thread.ahkTerminate()
    }
return

;SIBLING2
;===============
SIBLING1Thread.AhkAssign("SIBLING2ThreadPtr", (&SIBLING1Thread) "")
toggleSIBLING2 := 0 
SIBLING2G: 
    toggleSIBLING2 := !toggleSIBLING2
    if (toggleSIBLING2) {
		GuiControlGet, SIBLING1
		if (SIBLING1) {
			GuiControl,, SIBLING2, STOP CHECK WITH SIBLING 2
			SIBLING2Script := CriticalObject()
			script:="                           
			("      
				#NoEnv 
				#NoTrayIcon
				Loop
				{
					SIBLING1Thread := Object(SIBLING2ThreadPtr)
					SIBLING1Count := SIBLING1Thread.AhkGetVar.SIBLING1Count
					MsgBox % ""SIBLING 1 COUNT IS: "" SIBLING1Count
				}
			)"
			SIBLING2Thread:=AhkThread(script,&SIBLING2Script)
		} else {
			MsgBox, 1ST START SIBLING 1!
			GuiControl,, SIBLING2, CHECK WITH SIBLING 2
		}
    } else {
        SIBLING2Thread.ahkTerminate()
        GuiControl,, SIBLING2, CHECK WITH SIBLING 2
    }
return

GuiClose:
ExitApp
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 17:21

swagfag wrote:
10 Jul 2019, 17:05
u have bits of unreachable code, shoved in between labels and return statements
u believe we can all understand, but im not so sure, this all looks like complete gibberish to me. i dont understand what ure trying to do.
ure trying to, within thread2, obtain a ptr to thread2(a ptr, which u havent made available in any way), and then ure trying to fetch thread2's contradorfihlo1(a variable which was never assigned in thread2) ??
Hello bro!
I had put the whole code in, really was confused to understand. But above I put a summary, showing how it works. If you run, you'll understand. I have 2 threads running, I'm trying to communicate with each other by getting variables between them.

In the code below works perfectly, but I'm trying to adapt the way I usually do and I'm not getting it.

Code: Select all

Irmao01Script =         
(LTrim %`           
	#Persistent  
	FilhoMsg := "OI, EU SOU O FILHO!"
)
Irmao01Thread := AhkThread(Irmao01Script)

Irmao02Script =       
(LTrim %`              
	#Persistent    
	IrmaoMsg := "OI, EU SOU O IRMÃO!"
) 
Irmao02Thread := AhkThread(Irmao02Script)

Irmao01Thread.AhkAssign("Irmao02ThreadPtr", &Irmao02Thread "")
Irmao01Thread.AhkExec("    
(LTrim %`    
	Irmao02Thread := Object(Irmao02ThreadPtr) ; OU USE criticalobject()
	IrmaoMsg := Irmao02Thread.AhkGetVar.IrmaoMsg
	MsgBox % ""FILHO LÊ VARIÁVEL DO IRMÃO:`n"" IrmaoMsg
)")
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 17:42

again, u still have unreachable code, placed in between labels.
and i still dont understand what ure trying to do in the "sibling" script. lets pretend SIBLING1Thread.AhkAssign("SIBLING2ThreadPtr", (&SIBLING1Thread) "") was reachable and did run:
ure assigning in the thread s1 a pointer to the thread s1
then, in s2, ure trying to create an object from SIBLING2ThreadPtr(a variable which doesnt exist in s2)

also, stop using plain Objects when interacting with threads. ur script will inevitably crash. use CriticalObjects or synchronize with CriticalSections
Last edited by swagfag on 10 Jul 2019, 17:56, edited 3 times in total.
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 17:52

Parameter also needs to be a string!SIBLING1Thread:=AhkThread(script,"" (&SIBLING1Script)) but you seems never to use it.
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

10 Jul 2019, 20:53

After much trying, I got it!

Code: Select all

#NoEnv
#NoTrayIcon
#SingleInstance, Force

Gui, Add, Checkbox, h50 w400 vs1 gs1G, START COUNT WITH s1
Gui, Add, Button, h50 w400 vs2 gs2G, CHECK s1 WITH s2
Gui, Show, `t
return

;s1
;===============
s1G:
    toggles1 := !toggles1
    if (toggles1) {
        s1Script := CriticalObject()
        script1 := "                     
        ("     
            #NoEnv
            #NoTrayIcon
            Loop
            {
				s1Script := CriticalObject(A_Args[1])
                s1Count = %A_Index%
                ToolTip, s1 count: %s1Count%
            }
        )"
		s1Thread := AhkThread(script1, &s1Script "")
    } else {
        s1Thread.ahkTerminate()
    }
return

;s2
;===============
s2Thread.AhkAssign(&s1Thread "")
s2G: 
    toggles2 := !toggles2
    if (toggles2) {
		GuiControlGet, s1
		;if (s1) {    ;<- I commented to show the error, if s1 is not running, it has error.
			GuiControl, , s2, STOP CHECK WITH s2
			s2Script := CriticalObject(s1Thread)
			script2 := "                              
			("        
				#NoEnv 
				#NoTrayIcon
				Loop
				{
					s2Script := CriticalObject(A_Args[1])
					s1Count := s2Script.AhkGetVar.s1Count
					MsgBox % ""Count s1: "" s1Count
				}
			)"
			s2Thread := AhkThread(script2, &s2Script "")
		;} else {
			;MsgBox, 1ST CHECK s1!
			;GuiControl,, s2, CHECK WITH s2
		;}
    } else {
        s2Thread.ahkTerminate()
        GuiControl,, s2, CHECK WITH s2
    }
return

GuiClose:
ExitApp

Thank you all! :superhappy: But if there's anything that I can improve, I'll accept suggestion. Thank you again! :D
Last edited by manehscripts on 21 Jul 2019, 23:42, edited 2 times in total.
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

21 Jul 2019, 21:54

Hello!

How to prevent the error that it throws, if Thread that is sent the variable is not running?
I commented code above to show the error, if s1 is not running, it has error.

EDIT:
I've made a few attempts and I'm almost successful. But now only need to update the reading of s1 when I activate s2 first.
As I need it to work:
01 - I activate s2 first, and then activate s1.
02 - The count that s1 provides has to update the MsgBox of s2 without having to end s2 and start again. :crazy:

And if I'm doing something wrong and someone can help me in the right way, I'll be very grateful! :thumbup:

Code: Select all

#NoEnv
#NoTrayIcon
#SingleInstance, Force

Gui, Add, Checkbox, h50 w400 vs1 gs1G, START COUNT WITH s1
Gui, Add, Button, h50 w400 vs2 gs2G, CHECK s1 WITH s2
Gui, Show, `t
return

;s1
;===============
s1G:
    toggles1 := !toggles1
    if (toggles1) {
        script := "                     
        (
            #NoEnv
            #NoTrayIcon
            Loop
            {
                s1Count = `%A_Index`%
                ToolTip, s1 count: `%s1Count`%
            }
        )"
        while !s1Thread.ahkReady() {
            SoundBeep, 4000
            s1Thread := AhkThread(script)
			s1Active := 1
        }
    } else {
        while s1Thread.ahkReady() {
            SoundBeep, 8000
            s1Thread.ahkTerminate()
			s1Active := 0
        }
    }
return

;s2
;===============
s2Thread.AhkAssign(&s1Thread "")
s2G: 
    toggles2 := !toggles2
    if (toggles2) {
		GuiControl, , s2, STOP CHECK s1 WITH s2
		if !s1Thread.ahkReady() {   ; does not update information when activate s1 after executing s2, in addition to displaying an error.
			s1Thread := AhkThread(script)		; I may sound crazy, but it worked.
			s2Script := CriticalObject(s1Thread)
			s1Thread.ahkTerminate()		; I may sound crazy, but it worked.
		} else if s1Thread.ahkReady() {
			s2Script := CriticalObject(s1Thread)
		}
		script := "             
		(
			#NoEnv 
			#NoTrayIcon
			PaternThread := AhkExported()
			Loop
			{
				s1Active = `% PaternThread.AhkGetVar.s1Active   ; I've created a variable to check if s1 is running or not. But when I activate first s2 and then activate s1, it is not updated to the value of s1
				
				if (s1Active) {
					s2Script := CriticalObject(A_Args[1])
					s1Count := s2Script.AhkGetVar.s1Count
				} else {
					s1Count = STOPPED
				}
				MsgBox `% ""Count s1: ""s1Count
			}
		)"
        while !s2Thread.ahkReady() {
            SoundBeep, 4000
            s2Thread := AhkThread(script, (&s2Script) "")
        }
    } else {
        while s2Thread.ahkReady() {
            SoundBeep, 8000
            s2Thread.ahkTerminate()
        }
        GuiControl,, s2, CHECK s1 WITH s2
    }
return

GuiClose:
	while s1Thread.ahkReady() {
		SoundBeep, 8000
		s1Thread.ahkTerminate()
	}
	while s2Thread.ahkReady() {
		SoundBeep, 8000
		s2Thread.ahkTerminate()
	}
ExitApp
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
User avatar
rommmcek
Posts: 1470
Joined: 15 Aug 2014, 15:18

Re: About AhkThread (Parent, Child and Sibling)

22 Jul 2019, 04:47

MsgBox pauses the thread. To update you must either close MsgBox first or use custom display Gui instead.
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

22 Jul 2019, 08:43

rommmcek wrote:
22 Jul 2019, 04:47
MsgBox pauses the thread. To update you must either close MsgBox first or use custom display Gui instead.
Yes, I understand that MsgBox pauses the Thread, but from what I understand, the CriticalObject(A_Args[1]) within the Loop communicates with the CriticalObject(s1Thread) that is outside the Loot, maybe this should not be the correct form, but that's how I learned from other examples. So when s2 is already running, the Loop's CriticalObject(A_Args[1]) will not have the connection to what's outside it, so it'll only catch the info when I pause, and run it again. Can I do this automatic reading to no need to pause and start again?

ex01.gif
ex01.gif (400.4 KiB) Viewed 4857 times
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

22 Jul 2019, 11:40

I did several tests and I came to this conclusion successfully. But Idk if it's the correct form although it's working. If anyone can help me organize the code (if need be), please. :thumbup:

Code: Select all

#NoEnv
#NoTrayIcon
#SingleInstance, Force

Gui, Add, Checkbox, h50 w400 vs1 gs1G, START COUNT WITH s1
Gui, Add, Button, h50 w400 vs2 gs2G, CHECK s1 WITH s2
Gui, Show, `t
return

;s1
;===============
s1G:
    toggles1 := !toggles1
    if (toggles1) {
        script := "                     
        (
            #NoEnv
            #NoTrayIcon
            Loop
            {
                s1Count = `%A_Index`%
                ToolTip, s1 count: `%s1Count`%
            }
        )"
        while !s1Thread.ahkReady() {
            SoundBeep, 4000
            s1Thread := AhkThread(script)
			s1Active := 1
			if s2Thread.ahkReady() {    ; I checked the time to activate s1, so it works!
				s2Thread.ahkTerminate()
				toggles2 := 0
				gosub, s2G
			}
        }
    } else {
        while s1Thread.ahkReady() {
            SoundBeep, 8000
            s1Thread.ahkTerminate()
			s1Active := 0
        }
    }
return

;s2
;===============
s2Thread.AhkAssign(&s1Thread "")
s2G: 
    toggles2 := !toggles2
    if (toggles2) {
		GuiControl, , s2, STOP CHECK s1 WITH s2
		if !s1Thread.ahkReady() { 
			s1Thread := AhkThread(script)		; I may sound crazy, but it worked.
			s2Script := CriticalObject(s1Thread)
			s1Thread.ahkTerminate()		; I may sound crazy, but it worked.
		} else if s1Thread.ahkReady() {
			s2Script := CriticalObject(s1Thread)
		}
		script := "
		(
			#NoEnv 
			#NoTrayIcon
			Loop
			{
				PaternThread := AhkExported()
				s1Active = `% PaternThread.AhkGetVar.s1Active
				
				if (s1Active) {
					s2Script := CriticalObject(A_Args[1])
					s1Count := s2Script.AhkGetVar.s1Count
				} else {
					s1Count = STOPPED
				}
				MsgBox `% ""Count s1: ""s1Count
			}
		)"
        while !s2Thread.ahkReady() {
            SoundBeep, 4000
            s2Thread := AhkThread(script, (&s2Script) "")
        }
    } else {
        while s2Thread.ahkReady() {
            SoundBeep, 8000
            s2Thread.ahkTerminate()
        }
        GuiControl,, s2, CHECK s1 WITH s2
    }
return

GuiClose:
	while s1Thread.ahkReady() {
		SoundBeep, 8000
		s1Thread.ahkTerminate()
	}
	while s2Thread.ahkReady() {
		SoundBeep, 8000
		s2Thread.ahkTerminate()
	}
ExitApp
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: About AhkThread (Parent, Child and Sibling)

22 Jul 2019, 19:06

Try this:

Code: Select all

#NoTrayIcon
#SingleInstance, Force
share:=CriticalObject({count:0,s1Thread:"",s2Thread:""})
s1Script := "                     
(
	#NoTrayIcon
	share:=CriticalObject(" (&share) ")
	Loop
		ToolTip `% ""s1 count: "" ++share.count
)"
s2Script := "
(
	#NoTrayIcon
	share:=CriticalObject(" (&share) ")
	Loop
		MsgBox `% ""Count s1: "" share.s1Thread.ahkReady()?share.count:""STOPPED""
)"

Gui, Add, Checkbox, h50 w400 vs1 gs1G, START COUNT WITH s1
Gui, Add, Button, h50 w400 vs2 gs2G, CHECK s1 WITH s2
Gui, Show, `t
return

;s1
;===============
s1G:
    if (toggles1 := !toggles1) {
        if !s1Thread.ahkReady() {
            SoundBeep, 4000
            share.s1Thread := AhkThread(s1Script)
			if share.s2Thread.ahkReady() {
				share.s2Thread.ahkTerminate()
				toggles2 := 0
				goto, s2G
			}
        }
    } else {
		SoundBeep, 8000
		share.s1Thread.ahkTerminate()
		share.s2Thread.ahkTerminate()
		share.count:=0
		GuiControl,,s1,0
        GuiControl,, s2, CHECK s1 WITH s2
		toggles2:=0
	}
return

;s2
;===============
s2G: 
    if (toggles2 := !toggles2) {
		Gui,Submit,NoHide
		GuiControl, , s2, STOP CHECK s1 WITH s2
		GuiControl,,s1,1
		toggles1:=1
		if !share.s1Thread.ahkReady() { 
			share.s1Thread := AhkThread(s1Script)
		}
        if !share.s2Thread.ahkReady() {
            SoundBeep, 4000
            share.s2Thread := AhkThread(s2Script)
        }
    } else {
        if share.s2Thread.ahkReady() {
            SoundBeep, 8000
            share.s2Thread.ahkTerminate()
        }
        GuiControl,, s2, CHECK s1 WITH s2
		
    }
return

GuiClose:
	if share.s1Thread.ahkReady() {
		SoundBeep, 8000
		share.s1Thread.ahkTerminate()
	}
	if share.s2Thread.ahkReady() {
		SoundBeep, 8000
		share.s2Thread.ahkTerminate()
	}
ExitApp
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

23 Jul 2019, 21:30

HotKeyIt wrote:
22 Jul 2019, 19:06
Try this:
Hello @HotKeyIt ! :wave:
Thank you so much for the idea. :clap: I adjusted some things to be exactly as I need. Finally the code below.

Code: Select all

#NoTrayIcon
#SingleInstance, Force
share:=CriticalObject({count:0,s1Thread:"",s2Thread:""})
s1Script := "
(
	#NoTrayIcon
	share:=CriticalObject(" (&share) ")
	Loop,
    {
        Count := ++share.count
		ToolTip, s1 count: `%Count`%
    }
)"
s2Script := "
(
	#NoTrayIcon
	share:=CriticalObject(" (&share) ")
	Loop,
    {
        if share.s1Thread.ahkReady() {
            Count := share.count
            MsgBox, Count s1: `%Count`%
        } else {
            MsgBox, Count s1: STOPPED
        }
    }
)"

Gui, Add, Checkbox, h50 w400 vs1 gs1G, START COUNT WITH s1
Gui, Add, Button, h50 w400 vs2 gs2G, CHECK s1 WITH s2
Gui, Show, `t
return

;s1
;===============
s1G:
    if (toggles1 := !toggles1) {
        if !share.s1Thread.ahkReady() {
            SoundBeep, 4000
            share.s1Thread := AhkThread(s1Script)
        }
    } else {
        if share.s1Thread.ahkReady() {
            SoundBeep, 8000
            share.s1Thread.ahkTerminate()
        }
		share.count:=0
	}
return

;s2
;===============
s2G: 
    if (toggles2 := !toggles2) {
		GuiControl, , s2, STOP CHECK s1 WITH s2
        if !share.s2Thread.ahkReady() {
            SoundBeep, 4000
            share.s2Thread := AhkThread(s2Script)
        }
    } else {
        if share.s2Thread.ahkReady() {
            SoundBeep, 8000
            share.s2Thread.ahkTerminate()
        }
        GuiControl,, s2, CHECK s1 WITH s2
    }
return

GuiClose:
	if share.s1Thread.ahkReady() {
		SoundBeep, 8000
		share.s1Thread.ahkTerminate()
	}
	if share.s2Thread.ahkReady() {
		SoundBeep, 8000
		share.s2Thread.ahkTerminate()
	}
ExitApp
I have a question, please.

This is just an example of how I'm using it in my main code. In it there are 2 more Threads that work the same way, I just added to Share, example: share:=CriticalObject({count1:0,s1Thread:"",s2Thread:"",count2:0,s3Thread:"",s4Thread:""})
They work well between them. But I have several other independent threads, which work like the example below, and sometimes when I run several at the same time, the program crashes and stops working, having to be forced to close. Would there be any more correct way to work with other threads so that this error does not happen? I've been through the whole code and it seems to me that there is no error, it's some conflict between threads maybe.

Code: Select all

; This is an example of several threads that I use...
ExternalName := "Hello World"
OtherThread:
    toggleOtherThread := !toggleOtherThread
    if (toggleOtherThread) {
        scriptOtherThread := "
        (
            #NoEnv
            #NoTrayIcon
            ListLines Off
            #KeyHistory 0
            SendMode Input
            SetTitleMatchMode 2
            SetTitleMatchMode Fast
            SetDefaultMouseSpeed, 0
            Loop {
                Sleep, 100
                CoordMode, Tooltip
                CoordMode, Pixel, Screen
                CoordMode, Mouse
                PaternThread := AhkExported()
                ExternalName = `% PaternThread.AhkGetVar.ExternalName

                IfWinActive, WinNameExample  ; Just an example
                {
                    WinGetPos, X, Y, Width, Height, WinNameExample
                    PosXEnd := X+Width    
                    PosYEnd := Y+Height   
                    ImageSearch, PosXimg, PosYimg, `%X`%, `%Y`%, `%PosXEnd`%, `%PosYEnd`%, `%A_ScriptDir`%\Image.png
                    if (ErrorLevel==0) {
						MouseMove, `%PosXimg`%, `%PosYimg`%
						Sleep, 1000
						MsgBox, `%ExternalName`%, image found in `%PosXimg`%`,`%PosYimg`%
                    } else {
                        Sleep, 50
                    }
                } else {
                    Sleep, 1000
                }
            }
        )"
        if !DllOtherThread.ahkReady() {
			SoundBeep, 4000
            DllOtherThread := AhkThread(scriptOtherThread)
        }
    } else {
        if DllOtherThread.ahkReady() {
			SoundBeep, 8000
            DllOtherThread.ahkTerminate()
        }
    }
return
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: About AhkThread (Parent, Child and Sibling)

24 Jul 2019, 11:20

Use CriticalObject to communicate and share data between threads.
The only thing that can cause the crash is DllOtherThread as far as I can see, so having this in a CrticalObject and make sure that you clear it properly should solve the problem.
User avatar
manehscripts
Posts: 126
Joined: 03 May 2019, 16:10

Re: About AhkThread (Parent, Child and Sibling)

24 Jul 2019, 18:22

HotKeyIt wrote:
24 Jul 2019, 11:20
Use CriticalObject to communicate and share data between threads.
The only thing that can cause the crash is DllOtherThread as far as I can see, so having this in a CrticalObject and make sure that you clear it properly should solve the problem.
Hmm... @HotKeyIt
The crash happens suddenly, and I'm cleaning up according to the example I showed, using ahkTerminate(). Is this the correct form? Really, after I removed CriticalObject from my code it started to display this error.

And could you exemplify how insert CriticalObject in my example above? Idk how to assemble, Idk exactly where to add it. Previously I used CriticalObject(A_Args[1]) inside Thread and outside Script2 := CriticalObject() to connect to DllThread := AhkThread(script, (&Script2) ""), but I still don't quite understand if they are required, because now I'm using PaternThread := AhkExported(), so it has become unnecessary, although this may be the problem. :crazy:
-----------------------------------------------------------
Stop to think, shut up to resist, and act to win!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: About AhkThread (Parent, Child and Sibling)

25 Jul 2019, 05:52

Use the same way we used CriticalObject above (share) and do share.DllOtherThread....
If you can't get it right, post full example script.

Return to “Ask for Help”

Who is online

Users browsing this forum: jsong55 and 35 guests