I wanted to know how to pass a reference to a LIST control to another thread. I wanted to access the List’s properties in the new thread. For example, the maximum number of columns the list has:
?SomList{PROPLIST:Exists,0}
With Mark’s help I was able to make it work.
In my case I created a global TYPE’d GROUP to ease the passing of parameters to the new thread:
ThreadGroupType Group,TYPE
WindowRef &Window
ListRef Long
End
Congrats on taking the little information I mentioned about passing the window and FEQ and also the xWindow $ xFEQ {PROP:Yada} notation, and using that info to implement what you desired
I would make some very minor tweaks to what you posted:
I’d replace ThreadGrp.ListRef = ?List{PROP:FEQ}
with ThreadGrp.ListRef = ?List
Quite frankly I never saw the point of PROP:FEQ as you need it’s value to get it’s value.
I would replace
WindowAsParam PROCEDURE (string pParams) ! Declare Procedure
ThreadGrp LIKE(ThreadGroupType)
WindowWidth Long
MaxCols Long
CODE
ThreadGrp = pParams
Notice how the OVER eliminates the need for the assign ThreadGrp = pParams
Note: both approaches do rely on the correct string being passed, there is no strong typing here to help us.
If you weren’t planning on calling this directly as part of a START() (which requires all parameters to be STRINGS), then I would prototype as WindowAsParam PROCEDURE(*Window xWindow, SIGNED xFEQ)
This is just a matter of style and convention, but personally I would rename ListRef to ListFEQ or even just FEQ
where FEQ means Field EQuate , as we see in PROP:FEQ
I would consider renaming the group to say more about it’s contents
something like gtWinFEQ or WinFEQGroupType
It’s cool that you’re learning new stuff and thinking outside the box, but the accessing of properties of controls across threads seems like it’s approaching the edge of thread instability. Maybe not with the properties you’re currently reading, but if you want to go a whole lot further you might want to try a different path.
This kind of stuff that you’re doing sounds like it could be a good candidate for a class using the Capesoft GUTS interface that can chat back and forth beween objects.
If you have multiple windows and/or reports open, this is how you specify which one you’re talking about.
Its use is almost the same as calling SETTARGET before setting/getting properties.
Sometimes you gotta use SETTARGET, especially if you use functions that receive FEQ, that don’t also have a WINDOW param.
A caveat to using these target related prefixes though:
You have to be careful with how you name your window/report variables, keeping in mind that a FEQ is simply a field number. Be cognizant of which FEQ belong to which window, or else you could be referring to the incorrect control.
A way I use to Save and Restore the current Target using the lightly documented SYSTEM{PROP:Target}
WindowControlENum PROCEDURE(Window W) !Can also take REPORT or APPLICATIOPN
SaveTarget &Window,AUTO !Current Active Target
FEQ LONG,AUTO
CODE
SaveTarget &= SYSTEM{PROP:Target} !Save Current Target
SETTARGET(W)
LOOP
FEQ=0{PROP:NextField,FEQ}
IF ~Feq THEN BREAK.
!Debug info on FEQ
END
SETTARGET(SaveTarget) !Restore Target
RETURN
This is useful when wanting to work on a Window behind the currently active Window. E.g. you might use PROP:NextField to enumerate all the Controls.
For Reports in your embed code its ok to SETTARGET(Report) ; Feq{PROP:xxx}... ; SETTARGET(). I also tend to limit the scope of SetTarget() to one embed or a small range of lines.
I’m often moving things on the Report and find using PROP:XPos :YPos :Width :Height a bit verbose. I prefer to use GETPOSITION() and SETPOSITION() for 4x smaller code. They cannot use Report$ syntax so SetTarget() is required. It would be easy to create a Get/Set that passes REPORT so Report $ PROP’s can be used.
IMO its a bad idea to SETTARGET in Template inserted code as you may change a SETTARGET(Report) from the embed code. Another reason to follow Mark’s suggestion to use Report $ FEQ syntax. The reason I limit the scope of SetTarget() to one embed.
It’s important to know SETTARGET()with no parameter:
Resets TARGET to the topmost Window in the execution thread with the currently active ACCEPT loop.