Been bit by that local map thing, for sure.
Jeff I added/changed some things for these reasons:
- Prototype change WINDOW to REPORT. Works the same, more obvious to pass REPORT.
- For Header,Detail,Footer… types that cannot clone to WINDOW by return “
_Type_FEQ_#
” - If blank FEQ Name returned by ClaFieldNameRTL() then return "
_RptFEQ_#
’ - Open Dummy Window will change Target() so restore SetTarget(Report)
RptControlFEQName PROCEDURE(LONG ControlFEQ, REPORT ReportRef)!,STRING !works passing REPORT
DummyWindow WINDOW,AT(-10,-10,1,1)
END
CloneFEQ LONG,AUTO
TargetWas LONG,AUTO !Restore a SetTarget(Report) after Open/Close Window
NameFEQ CSTRING(128),AUTO
CODE
CASE ReportRef $ ControlFEQ{PROP:Type}
OF CREATE:Window ; NameFEQ='_Window' &'_FEQ_'& ControlFEQ &'_' !Passed (0,Window)
OF CREATE:Report ; NameFEQ='_Report' &'_FEQ_'& ControlFEQ &'_' !Passed (0,Report)
OF CREATE:Header ; NameFEQ='_Header' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Footer ; NameFEQ='_Footer' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Break ; NameFEQ='_Break' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Form ; NameFEQ='_Form' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Detail ; NameFEQ='_Detail' &'_FEQ_'& ControlFEQ &'_'
ELSE
TargetWas = SYSTEM{PROP:Target}
OPEN(DummyWindow)
CloneFEQ = CLONE(0,ControlFEQ,,,ReportRef) !Clone Rpt Control to Window
NameFEQ = ClaFieldNameRTL(CloneFEQ) !Can get FEQ Name from Window
IF NameFEQ <= ' ' THEN !If returned Blank / low ASCII
NameFEQ = '_RptFEQ_'& ControlFEQ &'_' ! Then tell caller FEQ#
END
CLOSE(DummyWindow)
IF TargetWas = ADDRESS(ReportRef) THEN SETTARGET(ReportRef).
END
RETURN NameFEQ
!======================= Global Map =======================
MAP
RptControlFEQName PROCEDURE(LONG ControlFEQ, REPORT ReportRef),STRING
MODULE('RTL') !This must be declared in the Global Map
ClaFieldNameRTL(LONG pFEQ),CSTRING,RAW,NAME('Cla$FIELDNAME'),DLL(dll_mode)
END
END
Below example of it working:
FeqNameReport_Example.zip (3.0 KB)
PROGRAM
MAP
TestMain PROCEDURE() !Test in procedure so data is not Global
RptControlFEQName PROCEDURE(LONG ControlFEQ, REPORT ReportRef),STRING !works fine passing REPORT
MODULE('RTL') !This must be declared in the Global Map
ClaFieldNameRTL(LONG pFEQ),CSTRING,RAW,NAME('Cla$FIELDNAME'),DLL(dll_mode)
END
MODULE('WinAPI')
OutputDebugString(*cstring Msg),PASCAL,RAW,NAME('OutputDebugStringA'),DLL(1)
END
ClaControlTypeName PROCEDURE(LONG CtrlPropType),STRING
DB PROCEDURE(STRING DebugText) !Debug Output
END
CODE
TestMain()
!============================================
TestMain PROCEDURE()
String1 STRING(40)
EndOfReport BYTE
Report REPORT('FEQName'),AT(1000,2000,6000,7000),FONT('Arial',10),PRE(RPT),THOUS
HEADER,AT(1000,1000,6000,1000),USE(?HEADER1)
STRING('Report Test FEQ Name'),AT(1740,94,2500),USE(?HeadStr1),TRN,CENTER,FONT(,,,FONT:bold)
STRING('(Clone to Window)'),AT(1740,292,2500),USE(?SubHeadStr1),TRN,CENTER,FONT(,,,FONT:bold)
BOX,AT(219,583,5573,219),USE(?BOX1),COLOR(COLOR:Black),FILL(COLOR:White),LINEWIDTH(1)
END
BreakEOR BREAK(EndOfReport),USE(?Break_EndOfReport)
DetailSKip DETAIL,AT(0,0,6000,542),USE(?DetailSKip)
STRING(@s40),AT(167,146),USE(String1)
STRING(@s40),AT(3167,146), USE(String1,, ?String1:skip),SKIP
LINE,AT(198,396,5500),USE(?LineDetail1)
END
END
FOOTER,AT(1000,9000,6000,250),USE(?FOOTER1)
END
FORM,AT(1000,1000,6000,9000),USE(?FORM1)
END
END
NextFEQ LONG
Dbg1 PSTRING(256)
DbgAll ANY
CODE
OPEN(Report)
DB('=== TOP == Enumerate Report Controls === '& Command('0') )
SetTarget(Report) !Safer to do this every LOOP, but FEQ Name has a SetTarget() fixup
NextFEQ = 0
LOOP
NextFEQ = Report{PROP:NextField,NextFEQ}
IF ~NextFEQ THEN BREAK.
Dbg1 = 'FEQ#=' & NextFEQ & |
'<9>Type='& NextFEQ{PROP:Type} & |
' '& ClaControlTypeName(NextFEQ{PROP:Type}) & |
' <9> FEQ Name=' & RptControlFEQName(NextFEQ,REPORT)
DB(Dbg1)
DbgAll = DbgAll & Dbg1 & '<13,10>'
END
DB('=== END ===')
Message(DbgAll,'RptControlFEQName() Example',Icon:Print1,,,MSGMODE:FIXEDFONT)
RETURN
!============================================================================
DB PROCEDURE(STRING xMessage)
Prfx EQUATE('FeqNameRpt: ') !All output gets this
sz CSTRING(SIZE(Prfx)+SIZE(xMessage)+3),AUTO
CODE
sz = Prfx & CLIP(xMessage) & '<13,10>'
OutputDebugString( sz )
RETURN
!============================================================================
ClaControlTypeName PROCEDURE(LONG CtrlPropType)!,STRING !Pass FEQ{PROP:Type} to get name e.g. Button
TypeName STRING(24)
CODE
!Edit: This was returning 'Window' if Zero is passed as Type. That is Wrong. Changed to Type?0
TypeName=CHOOSE(BAND(CtrlPropType,0FFh)+1,'Type?0', |
'SString','String','Image','Region','Line','Box','Ellipse','Entry','Button','Prompt',| !1-10
'Option','Check','Group','List','Combo','Spin','Text','Custom','Menu','Item',| !11-20
'Radio','MenuBar','Create23','Application','Window','Report','Header','Footer','Break','Form',| !21-30
'Detail','Ole','Droplist','Dropcombo','Progress','Slider','Sheet','Tab','Panel','TextRtf',| !31-40
'Text_SingleLine','Check3','Type?' & CtrlPropType) !41-42
CASE CtrlPropType
OF CREATE:ToolBar ; TypeName='ToolBar' !ToolBar is 128
OF CREATE:SubList ; TypeName='SubList-' & TypeName !DropList is 270=10Eh CREATE:sublist EQUATE(CREATE:list + 0100H)
OF CREATE:SubList+1 ; TypeName='ButtonDrop-' & TypeName !DropButto is 271=10Fh CREATE:sublist EQUATE(CREATE:list + 0100H)
OF 100h TO 100h+42 !CREATE:sublist EQUATE(CREATE:list + 0100H)
TypeName='SubList-' & TypeName
END
RETURN CLIP(TypeName)
!============================================================================
! Changes to RptControlFEQName:
! 1. Prototype change WINDOW to REPORT. Works the same, more obvious to pass REPORT.
! 2. For Header,Detail,Footer... types that cannot clone to WINDOW by return "`_Type_FEQ_#`"
! 3. If blank FEQ Name returned by ClaFieldNameRTL() then return "`_RptFEQ_#`'
! 4. Open(DummyWindow) will change Target() so restore SetTarget(Report)
!============================================================================
RptControlFEQName PROCEDURE(LONG ControlFEQ, REPORT ReportRef)!,STRING !works passing REPORT
!To get a Report Control USE(FeqName) clone it to a Window
DummyWindow WINDOW,AT(-10,-10,1,1)
END
CloneFEQ LONG,AUTO
TargetWas LONG,AUTO !Restore a SetTarget(Report) after Open/Close Window
NameFEQ CSTRING(128),AUTO
CODE
CASE ReportRef $ ControlFEQ{PROP:Type}
OF CREATE:Window ; NameFEQ='_Window' &'_FEQ_'& ControlFEQ &'_' !Passed (0,Window)
OF CREATE:Report ; NameFEQ='_Report' &'_FEQ_'& ControlFEQ &'_' !Passed (0,Report)
OF CREATE:Header ; NameFEQ='_Header' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Footer ; NameFEQ='_Footer' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Break ; NameFEQ='_Break' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Form ; NameFEQ='_Form' &'_FEQ_'& ControlFEQ &'_'
OF CREATE:Detail ; NameFEQ='_Detail' &'_FEQ_'& ControlFEQ &'_'
ELSE
TargetWas = SYSTEM{PROP:Target}
OPEN(DummyWindow)
CloneFEQ = CLONE(0,ControlFEQ,,,ReportRef) !Clone Rpt Control to Window
NameFEQ = ClaFieldNameRTL(CloneFEQ) !Can get FEQ Name from Window
IF NameFEQ <= ' ' THEN !If returned Blank / low ASCII
NameFEQ = '_RptFEQ_'& ControlFEQ &'_' ! Then tell caller FEQ#
END
CLOSE(DummyWindow)
IF TargetWas = ADDRESS(ReportRef) THEN SETTARGET(ReportRef).
END
RETURN NameFEQ
3 Likes