How to pass a v-variable? Topic is solved

Get help with using AutoHotkey and its commands and hotkeys
newbieforever
Posts: 447
Joined: 24 Aug 2016, 03:34

How to pass a v-variable?

29 Jan 2019, 07:39

Hi! This maybe looks like a funny programming style, but please assume there's a point to this.

The following demo works only if the v-variables are set as global. How this could be avoided?

(Instead of the label inside this function another function could be used; no labels outside a frunction should be used.)

Code: Select all

MakeGui()

RETURN

MakeGui() {
  Global vEdit1, vEdit2
  Gui Test: Default
  Gui Test: Add, Edit, w570 vvEdit1, Something
  Gui Test: Add, Edit, w570 vvEdit2, Else
  Gui Test: Show, w600
  TestGuiDropFiles:
    If !A_GuiEvent
  	  Return
    MsgBox %A_GuiEvent%
    If A_GuiControl in vEdit1     ; ,vEdit2
      GuiControl Test: , %A_GuiControl%, %A_GuiEvent%
    Return
  }
User avatar
nnnik
Posts: 4475
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: How to pass a v-variable?

29 Jan 2019, 07:54

Use the hWND to identify the control and instead of using DUI,Submit to ouptut the GUIs data use GUIControlGet with the hWND.
Recommends AHK Studio
newbieforever
Posts: 447
Joined: 24 Aug 2016, 03:34

Re: How to pass a v-variable?

29 Jan 2019, 14:13

Thank you, nnnik!

I understand which direction your clue goes, but I can't get any further yet. Within the label Hwnd is suddenly not available. But I certainly haven't understood you well enough yet...

Code: Select all

MakeGui()

RETURN

MakeGui() {
  Gui Test: Add, Edit, w570 hWndEd1, Something
  Gui Test: Add, Edit, w570 hWndEd2, Else
  Gui Test: Show, w600
	GuiControlGet, GuiCtrl, , %Ed1%
	MsgBox % GuiCtrl						; >>> OK
  TestGuiDropFiles:
    If !A_GuiEvent
  	  Return
	GuiControlGet, GuiCtrl, , %Ed1%
	MsgBox % GuiCtrl						; >>> NOT OK
    If A_GuiControl in %GuiCtrl%
      GuiControl Test: , %GuiCtrl%, %A_GuiEvent%
    Return
  }
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
GitHub: AAhkUser
Location: France

Re: How to pass a v-variable?

29 Jan 2019, 16:29

To use GuiControlGet using the hwnd you must first find a way to determine wich hwnd is at stake in your situation.
Yet A_GuiControl will contain the first 63 characters of the control's text/caption if it lacks an associated variable - which is not a reliable way to identify the control.
Otherwise, if you specify an associated variable, it must be, if you want to use it as GUI control variable from within a subroutine within a function and as per the documentation, global (not static).
So, to answer your question: no, this cannot be avoided using this design unless you can reliably identify your controls by their text/caption.


[EDIT] Or, at very least, in the specific situation of dropfiles there's actually a workaround:

Code: Select all

MakeGui()
RETURN

MakeGui() {

	static ; assume-static mode 

	GUI Test:+LastFoundExist
	IfWinExist
		return
	GUI Test: Add, Edit, w570 hwndhEdit1, Something
	GUI Test: Add, Edit, wp hwndhEdit2, Else
	GUI Test: Show, w600
	return

	TestGuiDropFiles:
		if not (A_GuiEvent)
	return
		MouseGetPos,,,, mHwnd, 2 ; retrieves the hwnd of the control the mouse is currently hovering over
		if (mHwnd = hEdit1) {
			GuiControl,, % hEdit1, % A_GuiEvent
		}
	return

}
my scripts
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: How to pass a v-variable?

29 Jan 2019, 16:58

Use "Static Control := []" object, then store controls' hwnd in Control["Ed1"], Control["Ed2"], etc, etc through "TempControlId" variable!

Code: Select all

MakeGui()

RETURN

MakeGui() {

Static Control := []

  Gui Test: Add, Edit, w570 hWndTempControlId, Something
  Control["Ed1"] := TempControlId

  Gui Test: Add, Edit, w570 hWndTempControlId, Else
  Control["Ed2"] := TempControlId


  Gui Test: Show, w600
	GuiControlGet, GuiCtrl, , % Control["Ed1"]
	MsgBox % GuiCtrl						; >>> OK
  TestGuiDropFiles:
    If !A_GuiEvent
  	  Return
	GuiControlGet, GuiCtrl, , % Control["Ed1"]
	MsgBox % GuiCtrl						; >>> NOT OK
    If A_GuiControl in %GuiCtrl%
      GuiControl Test: , %GuiCtrl%, %A_GuiEvent%
    Return
  }
newbieforever
Posts: 447
Joined: 24 Aug 2016, 03:34

Re: How to pass a v-variable?

30 Jan 2019, 10:12

Thank you, A_AhkUser & User!!!

I tend to use your MouseGetPos workaround, A_AhkUser. The demo works fine. Unfortunately I am not able to integrate a loop for all relevant controls. My attempt below doesn't work...

Code: Select all

MakeGui()

RETURN

MakeGui() {
	
  Static 
  Global Text := "Something"
  Gui Test: Add, Edit, w570 Hwndh1 
  Gui Test: Add, Edit, wp   Hwndh2
  Gui Test: Add, Edit, wp   Hwndh3, % Text 
  Gui Test: Show, w600
  Return

  TestGuiDropFiles:
	MouseGetPos,,,, mHwnd, 2
/* This works fine:
	If (mHwnd = h1)
  	  GuiControl Test: , % h1, % A_GuiEvent
*/
    Loop, 2
 	  If (mHwnd = h%A_Index%)
  	    GuiControl Test: , % h%A_Index%, % A_GuiEvent
		
	Return
  }
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
GitHub: AAhkUser
Location: France

Re: How to pass a v-variable?

30 Jan 2019, 15:54

@User
Simple and nice solution :thumbup:
newbieforever wrote:
30 Jan 2019, 10:12
Unfortunately I am not able to integrate a loop for all relevant controls. My attempt below doesn't work...
@newbieforever
This is because, as per the documentation:
When a function is entered by a subroutine thread, any references to dynamic variables made by that thread are treated as globals (including commands that create arrays).
(my underline).

I suggest you implement the User's method instead - for example:

Code: Select all

MakeGui("Something", "Something else", "Something else again")
RETURN

MakeGui(captions*) {

	static ; assume-static mode
	controls := []

	GUI Test:+LastFoundExist
	IfWinExist
		return
	for index, caption in captions {
		GUI Test: Add, Edit, w570 vvEdit%index% hwndhEdit%index%, % caption
		controls[ "vEdit" . index ] := hEdit%index%
	}
	GUI Test: Show, AutoSize
	return

	TestGuiDropFiles:
		if not (A_GuiEvent)
	return
		; ToolTip % A_GuiControl "|" controls[ A_GuiControl ]
		if A_GuiControl in vEdit1,vEdit2
			GuiControl,, % controls[ A_GuiControl ], % A_GuiEvent
	return

}
my scripts
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: How to pass a v-variable?  Topic is solved

30 Jan 2019, 16:40

A_AhkUser wrote:
30 Jan 2019, 15:54
Thanks!

@newbieforever, this is your best way to go:

Code: Select all

MakeGui()

RETURN

Testguiclose:	;__________________
exitapp

MakeGui() {	;_______________________________
	
  Static Static := []

  Gui Test: Add, Edit, w570 HwndTempCtrlId
  Static["Gui_Ed1"] := TempCtrlId

  Gui Test: Add, Edit, wp   HwndTempCtrlId
  Static["Gui_Ed2"] := TempCtrlId

  Gui Test: Add, Edit, wp   HwndTempCtrlId
  Static["Gui_Ed3"] := TempCtrlId

  Gui Test: Add, Edit, wp   HwndTempCtrlId, Excluded
  Static["Gui_Ed4"] := TempCtrlId

  Gui Test: Show, w600

  Return

TestGuiDropFiles:	;__

MouseGetPos,,,, mHwnd, 2

	Loop, 3
	{
 		If (mHwnd = Static["Gui_Ed" a_index])
		{
  		GuiControl Test: , % Static["Gui_Ed" a_index], % A_GuiEvent
		
		Return
		}
	}

return
}
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: How to pass a v-variable?

30 Jan 2019, 16:51

or

Code: Select all

MakeGui()
RETURN


MakeGui() {	;_______________________________
	
Static Static := []

gui, Test:Default

	loop, 4
	{
	if (a_index = 4)
	Text := "Exclude"

	Gui, Add, Edit, w570 HwndTempCtrlId, % Text
	Static["Gui_Ed" a_index] := TempCtrlId
	}

Gui, Show, w600

Return

TestGuiDropFiles:	;__

MouseGetPos,,,, mHwnd, 2

	Loop, 3
	{
 		If (mHwnd = Static["Gui_Ed" a_index])
		{
  		GuiControl Test: , % Static["Gui_Ed" a_index], % A_GuiEvent
		
		Return
		}
	}

return

Testguiclose:	;__
exitapp
return
}
newbieforever
Posts: 447
Joined: 24 Aug 2016, 03:34

Re: How to pass a v-variable?

31 Jan 2019, 07:50

Thank you, A_AhkUser & User!!! Each of you both is a schatz!!!

I will use your method, User, which is a little more transparent for me as a newbie.

(Btw, I was extremely surprised (as a newbie, of course) by these multiple problems araising from the fact that a gui definition and a label are used inside a function...)
User
Posts: 407
Joined: 26 Jun 2017, 08:12

Re: How to pass a v-variable?

31 Jan 2019, 08:37

newbieforever wrote:
31 Jan 2019, 07:50
Thank you, A_AhkUser & User!!! Each of you both is a schatz!!!

I will use your method, User, which is a little more transparent for me as a newbie.

(Btw, I was extremely surprised (as a newbie, of course) by these multiple problems araising from the fact that a gui definition and a label are used inside a function...)
You welcome!

You just need 1 Static variable in order to solve all those multiple problems you mentioned above! (in this case, we defined "Static" variable as an static variable inside the function!)

Return to “Ask For Help”

Who is online

Users browsing this forum: AHKStudent, anv, BeSu, Lee James, mikeyww, Odlanir, TXShooter and 55 guests