Page 1 of 1

How to pass a v-variable?

Posted: 29 Jan 2019, 07:39
by newbieforever
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
  }

Re: How to pass a v-variable?

Posted: 29 Jan 2019, 07:54
by nnnik
Use the hWND to identify the control and instead of using DUI,Submit to ouptut the GUIs data use GUIControlGet with the hWND.

Re: How to pass a v-variable?

Posted: 29 Jan 2019, 14:13
by newbieforever
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
  }

Re: How to pass a v-variable?

Posted: 29 Jan 2019, 16:29
by A_AhkUser
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

}

Re: How to pass a v-variable?

Posted: 29 Jan 2019, 16:58
by User
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
  }

Re: How to pass a v-variable?

Posted: 30 Jan 2019, 10:12
by newbieforever
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
  }

Re: How to pass a v-variable?

Posted: 30 Jan 2019, 15:54
by A_AhkUser
@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

}

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

Posted: 30 Jan 2019, 16:40
by User
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
}

Re: How to pass a v-variable?

Posted: 30 Jan 2019, 16:51
by User
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
}

Re: How to pass a v-variable?

Posted: 31 Jan 2019, 07:50
by newbieforever
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...)

Re: How to pass a v-variable?

Posted: 31 Jan 2019, 08:37
by User
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!)