In case of BTNBMP, we can write ACTION MsgInfo( ::cCaption )
In case of BUTTON on BUTTONBAR we can write ACTION MsgInfo( oThis:cCaption )
This is because the BtnBmp class evaluates the bAction codeblock with the button object as paramter.
TButtonBmp and its parent class TButton do not pass any parameter while evaluating the bAction block.
It is desirable to modify the TButton class and change the line 176 ( version 10.6 ) as Eval( ::bAction, Self )
Then we can write ACTION {|oBtn| MsgInfo( oBtn:<anydata>)}
Without changing the FWH library you may:
- Code: Select all Expand view RUN
FOR I:=1 to 6
@ 200,100 BUTTONBMP aBtn[I] OF oGrund ;
PROMPT STR(I) PIXEL SIZE 50,50 ;
MESSAGE "Abbruch"
aBtn[I]:bAction := MyActionBlock( aBtn, i )
aBtn[I]:lDrag := .t.
next
static function MyActionBlock( aBtn, i )
return { || MsgInfo( aBtn[i]:<anydata> )}
We can not write " ... ACTION MsgInfo( aBtn[i]:<data> ). By the time this codeblock is executed the value of i is 7.
The function MyActionBlock uses the concept of detached locals. The function uses the values of aBtn and i, at the time of calling the function, for preparing the codeblock and the values are local to this function and do not change.
This is the way to create codeblocks within loops.
ALTERNATIVELY:
- Code: Select all Expand view RUN
FOR I:=1 to 6
@ 200,100 BUTTONBMP aBtn[I] OF oGrund ;
PROMPT STR(I) PIXEL SIZE 50,50 ;
MESSAGE "Abbruch"
aBtn[I]:OnClick := { |o| MsgInfo( o:cCaption ) }
aBtn[I]:lDrag := .t.
next
In addition to bAction, there is another little known data oBtn:OnClick. This can also be used.