Address of the listbox's queue

Is it possible to get at-runtime the address of the queue that is a data source for a listbox? I mean the queue specified in the FROM attribute.

Unfortunately, PROP:From is just a setter (write-only).

Regards,
Andrzej

The List From QUEUE Reference Address is available starting in 11.0.13505 with undocumented PROP 7A23h that was probably added for Any Screen.

Here’s some code to get the From() &Queue reference from my Clarion Folders that shows a use for it. There is code in there to prevent some values that will crash when there is no FROM(), it’s FROM(‘a |string |of |choices’) or a VLB.

ListFromQProp   PROCEDURE(LONG ListFEQ) !,LONG  -  Wrap code to get 7A23h &Queue to protect from GPF
FromQ LONG
FromP LONG
PROP:FromPtr  EQUATE(7A0EH) !ABLLIST.INT &= IMappedListContents ? 0800xxxxH usually, 7C98h also an II ptr?
PROP:FromQRef EQUATE(7A23H) !Showed up in 13505 = &QUEUE unless no FROM(Q) then ?= Interface for WB see 0800xxxxh
  CODE
  IF ~ListFEQ{PROP:From} AND ListFEQ{PROP:VLBval}=0 THEN    !From('Text') or VLB &A23h would return a pointer that GPFs 
     FromQ=ListFEQ{PROP:FromQRef}                           !The New 11.13505 Property of LIST for FROM(Q)
     IF FromQ=08004FF0h THEN FromQ=0.                       !If No From(Q) RTL {7A23h}=08004FF0h always ????
     IF FromQ THEN 
        FromP=ListFEQ{PROP:FromPtr} 
        IF ABS(FromQ-FromP)<7FFFh THEN FromQ=0. !HACK - Interface pointer?  not From(Q), can't use this.
     END                                        !       This would only happen with No FROM() at all.
     IF FromQ>0 AND FromQ<=4096 THEN FromQ=0.   !Null Pointer memory region
  END
  RETURN FromQ

Q_Addr LONG
Q_Ref  &QUEUE
  Q_Addr = ListFromQProp(?Browse:Queue)
  IF Q_Addr THEN Q_Ref &= (Q_Addr).

If you are not up to 13505, or just a safer alternative, is to write template to generate the code to store it at runtime in a User Property or Local variable. Here’s an except that store it in ?List{‘FromQ’}:

#AT(%AfterWindowOpening),WHERE(~%DoNotGenerate)
  #! CBWndPrvListFromQ.TPL
  #FOR(%CONTROL),WHERE(%ControlType='LIST' OR %ControlType='DROP' OR %ControlType='COMBO')
    #SET(%FromQ,EXTRACT(%ControlStatement,'FROM',1)) 
    #IF(%FromQ AND 0=INSTRING(CHR(39),%FromQ,1,1))
 CBListPropFromQ(%Control,%FromQ,'%FromQ') !Tpl CBWndPrvListFromQ
    #ENDIF
  #ENDFOR   
#EndAT
#!-------------
#AT(%GlobalMap),WHERE(~%DoNotGenerate)
    CBListPropFromQ(LONG FEQ,*QUEUE FrmQ,<STRING NameQ>)
#EndAT
#!-------------
#AT(%ProgramProcedures),WHERE(~%DoNotGenerate)
CBListPropFromQ PROCEDURE(LONG FEQ,*QUEUE FrmQ,<STRING NameQ>)
Ref GROUP,AUTO
Q    &QUEUE
L    LONG,OVER(Q)
  END
  CODE
  Ref.Q &=FrmQ 
  FEQ{'FromQ'}=Ref.L 
  FEQ{'FromWho'}=CHOOSE(~OMITTED(NameQ),NameQ,'Queue' & Ref.L)
  RETURN
#EndAT
2 Likes

Amazing stuff, Carl. No idea where you get such information, but I do hope you never get another life. :grinning:

3 Likes

Hello Carl, many thanks for this detailed information! It’s very helpful.

Best regsrds,
Andrzej