Dec 102017
Adds Wrap Capability to ACHOICE Menus in Clipper. | |||
---|---|---|---|
File Name | File Size | Zip Size | Zip Type |
ACWRAP.DOC | 2671 | 1241 | deflated |
Download File ACWRAP.ZIP Here
Contents of the ACWRAP.DOC file
Adding Wrap Capability to ACHOICE Menus in Clipper
--------------------------------------------------
Clipper's ACHOICE function is very convenient for creating menus from arrays
but I find it annoying that it is implemented so that the menus do not wrap
when reaching the top or bottom (the SET WRAP ON command provided for
MENU TO does not affect ACHOICE). After quite a bit of trial and error, I
came up with this method for making ACHOICE menus wrap.
When called with the name of a user function, ACHOICE passes the function
three variables, one of which is the currently highlighted array element.
By checking the last key pressed and the current element, you can determine
if a wrap is necessary (i.e., if the current element is the first and the
last key was the up arrow, or the element is the last one and the last key
was the down arrow).
As it turns out, doing this is complicated somewhat by the fact that the
AC_ELEM (as I'm calling it here) parameter passed to the user function gives
the array element current AFTER the last keystroke, whereas we need the element
BEFORE the keystroke. Therefore, it must be done by initializing a variable
which I'm calling LAST_ELEM to 1 BEFORE calling ACHOICE and then resetting it
to AC_ELEM at the END of the user function. I discovered this when I
initially wrote the function without using LAST_ELEM; by using AC_ELEM in
my CASE statements (i.e., CASE LASTKEY()=5 .AND. AC_ELEM=1). This resulted
in wrapping occuring on the second element with the up arrow and on the
second to last element with the down arrow, which is worse than not wrapping!
This explanation may or may not be clear, but the code which follows does
work. Please send any comments, or alternative ways of doing this.
Glenn Alcott CompuServe ID: 76044,747
*******************************************************************************
DUMMY="" && Not using option of second array indicating availability
LAST_ELEM=1
CH=ACHOICE(R1,C1,R2,C2,MENU_ARRAY,DUMMY,"AC_FUNC")
*
FUNCTION AC_FUNC
* User function called by ACHOICE
* AC_MODE and AC_SCR are not used by this function but are passed automatically
PARAM AC_MODE,AC_ELEM,AC_SCR
DO CASE
CASE LASTKEY()=24 .AND. LAST_ELEM=LEN(MENU_ARRAY) && Down arrow on last element
KEYBOARD CHR(31) && Send Ctrl-PgUp to go to top
R=2 && This return value indicates that ACHOICE should continue
CASE LASTKEY()=5 .AND. LAST_ELEM=1 && Up arrow on first element
KEYBOARD CHR(30) && Send Ctrl-PgDn to go to bottom
R=2
CASE
...
Insert case statements for other keys you want to handle
...
ENDCASE
LAST_ELEM=AC_ELEM
RETURN R
--------------------------------------------------
Clipper's ACHOICE function is very convenient for creating menus from arrays
but I find it annoying that it is implemented so that the menus do not wrap
when reaching the top or bottom (the SET WRAP ON command provided for
MENU TO does not affect ACHOICE). After quite a bit of trial and error, I
came up with this method for making ACHOICE menus wrap.
When called with the name of a user function, ACHOICE passes the function
three variables, one of which is the currently highlighted array element.
By checking the last key pressed and the current element, you can determine
if a wrap is necessary (i.e., if the current element is the first and the
last key was the up arrow, or the element is the last one and the last key
was the down arrow).
As it turns out, doing this is complicated somewhat by the fact that the
AC_ELEM (as I'm calling it here) parameter passed to the user function gives
the array element current AFTER the last keystroke, whereas we need the element
BEFORE the keystroke. Therefore, it must be done by initializing a variable
which I'm calling LAST_ELEM to 1 BEFORE calling ACHOICE and then resetting it
to AC_ELEM at the END of the user function. I discovered this when I
initially wrote the function without using LAST_ELEM; by using AC_ELEM in
my CASE statements (i.e., CASE LASTKEY()=5 .AND. AC_ELEM=1). This resulted
in wrapping occuring on the second element with the up arrow and on the
second to last element with the down arrow, which is worse than not wrapping!
This explanation may or may not be clear, but the code which follows does
work. Please send any comments, or alternative ways of doing this.
Glenn Alcott CompuServe ID: 76044,747
*******************************************************************************
DUMMY="" && Not using option of second array indicating availability
LAST_ELEM=1
CH=ACHOICE(R1,C1,R2,C2,MENU_ARRAY,DUMMY,"AC_FUNC")
*
FUNCTION AC_FUNC
* User function called by ACHOICE
* AC_MODE and AC_SCR are not used by this function but are passed automatically
PARAM AC_MODE,AC_ELEM,AC_SCR
DO CASE
CASE LASTKEY()=24 .AND. LAST_ELEM=LEN(MENU_ARRAY) && Down arrow on last element
KEYBOARD CHR(31) && Send Ctrl-PgUp to go to top
R=2 && This return value indicates that ACHOICE should continue
CASE LASTKEY()=5 .AND. LAST_ELEM=1 && Up arrow on first element
KEYBOARD CHR(30) && Send Ctrl-PgDn to go to bottom
R=2
CASE
...
Insert case statements for other keys you want to handle
...
ENDCASE
LAST_ELEM=AC_ELEM
RETURN R
December 10, 2017
Add comments