From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 13-MAR-1993 01:46:13.11
To:	Info-VAX@KL.SRI.COM
CC:	
Subj:	Re: VAX/VMS Menu Utilities...

In article <01GVLM8LHO3M00143W@RCKHRST2.BITNET>, "Scott R. Daniels" <SRDANIELS%RCKHRST2.bitnet@vmd.cso.uiuc.edu> writes:
> 
> Hello VAX Gurus,
> 
> 
>    Once again, I have a few simple questions to ask:
> 
> 
>         1) Are there any *FREE*(or CHEAP) VMS Menu programs available ?
> 
>         2) Are there any *FREE*(or CHEAP) VMS "XTREE-like" programs available ?
> 
> 
>    I have already looked into Q*Menu and Q*File, but they are *VERY* expensive !
>    Thanks in advance....
> 


What follows is some C code to do vertical menuing.  Its a freebie...


-- 
Dean Sheets                ^  "The Dreamer..."                                 
Inland Steel Research Labs ^  Internet:  Sheets@Inland.com
East Chicago, IN          _|_ UUCP:      ...!uunet!Inland!Sheets    
219 399 8043               |  Quality Starts on the Inside...   


$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On 17-SEP-1991 11:31:24.63   By user SHEETS 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. COMP_AND_LINK.COM;1
$!       2. SHARE.OPT;2
$!       3. VMENU.C;9
$!       4. VTEST.COM;25
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X$Set Ver
X$CC Vmenu
X$Link vmenu,share.opt/opt
X$Set Nover
$ CALL UNPACK COMP_AND_LINK.COM;1 388455658
$ create 'f'
XSYS$SHARE:VAXCRTL.EXE          /SHARE
$ CALL UNPACK SHARE.OPT;2 1177693836
$ create 'f'
X/*
X*                                                                        `20
V     `20
X*  This software was developed using the resources of the Inland Steel Resea
Vrch`20
X*  Laboratories. It is available for unlimited distribution in the public
V      `20
X*  domain with the inclusion of this notice.
V                                   `20
X*
X**++
X**  FACILITY:
X**
X**   Vmenu.C
X**
X**  ABSTRACT:
X**
X**  Function which creates a vertical menu`20
X**  Pastes it anywhere on the screen`20
X**  Makes a selection thru arrow keys or 1st Letter
X**  And places the Selection in the passed parameter
X**  Screen refreshes with Control R or Control W
X**  AUTHOR:
X**
X**      Dean Sheets - Inland Steel Research Laboratories  Sheets@Inland.Com
X**      219-399-8043
X**
X**  CREATION DATE:     8/2/89
X**
X**  PARAMETERS:
X**    argc                == Total # of command line parameters
X**    argv                == Array of Menu Items
X**    argv`5B0`5D             == Holds name the program was invoked by
X**    argv`5B1`5D choice      == Holds number of Selection Chosen
X**    argv`5B2`5D row         == Starting Row
X**    argv`5B3`5D col         == Starting Col
X**    argv`5B4`5D menu.width  == Holds menu.width of Menu if desired
X**    argv`5B5`5D menu.title  == Menu Title
X**    argv`5B6-num.items+6`5D == Menu items
X**
X**  MODIFICATION HISTORY:
X**--
X**
X**  INCLUDE FILES
X**
X**/
X#include smgdef
X#include string
X#include stdio
X#include ssdef
X#include descrip
X
Xmain(int argc, char *argv`5B`5D)
X
X `7B  long     mrow=0,row=0,col=0,num_items=0,width=0,height=0;
X    long     choicerow=0,choicelen=0;
X    int      keystroke=0,choice=0,startchoice=0,cnt=0;
X    unsigned keyboard_id, display_id, pull_down;
X    char     schoice`5B2`5D, linetext`5B80`5D, symtext`5B80`5D, lchoicetext`
V5B10`5D, *pml;
X
X  /* Set up descriptors for text strings */
X    $DESCRIPTOR(menu_line,linetext);
X    $DESCRIPTOR(symbol,symtext);
X    $DESCRIPTOR(lchoice,lchoicetext);
X
X  /* Get the value of the symbol they passed   */
X    symbol.dsc$w_length = strlen(argv`5B1`5D);
X    strncpy(symtext, argv`5B1`5D, strlen(argv`5B1`5D));
X    LIB$GET_SYMBOL(&symbol, &symbol);
X
X  /* Convert selected pointer array parameters */
X    sscanf(symtext, "%d", &choice);
X    sscanf(argv`5B2`5D, "%d", &row);
X    sscanf(argv`5B3`5D, "%d", &col);
X    sscanf(argv`5B4`5D, "%d", &width);
X    num_items = argc;
X    height    = (argc - 6);
X
X  /* Find the Max Length of a Menu Item */
X  for (cnt=6; cnt<num_items; cnt++)
X    `7Bstrncpy(linetext,argv`5Bcnt`5D,80);
X      if (strlen(linetext) > width) width = strlen(linetext);
X    `7D
X
X  /* Make sure the Title will fit */
X  strncpy(linetext, argv`5B5`5D, 80);
X  menu_line.dsc$w_length = strlen(argv`5B5`5D);
X  if ((menu_line.dsc$w_length > width)) width = menu_line.dsc$w_length;
X  width += 2;
X
X  SMG$CREATE_VIRTUAL_DISPLAY(&height, &width, &display_id, &SMG$M_BORDER);
X  SMG$CREATE_PASTEBOARD(&pull_down);
X
X  /* Label the Border if a Title was Passed */
X  SMG$LABEL_BORDER(&display_id, &menu_line, &SMG$K_TOP, 0, &SMG$M_BOLD);
X
X  for (cnt=6; cnt<num_items; cnt++)
X    `7Bstrcpy(linetext, argv`5Bcnt`5D);
X     menu_line.dsc$w_length = (strlen(argv`5Bcnt`5D)+1);
X     pml = linetext;
X     mrow = (cnt-5);
X     SMG$PUT_CHARS(&display_id, &menu_line, &mrow, &2, 0, &SMG$M_BOLD);
X     strcpy(linetext, ++pml);
X     menu_line.dsc$w_length = (strlen(pml)+1);
X     SMG$PUT_CHARS(&display_id, &menu_line, &mrow, &3, 0, &SMG$M_NORMAL);
X    `7D
X  SMG$PASTE_VIRTUAL_DISPLAY(&display_id, &pull_down, &row, &col);
X
X  SMG$CREATE_VIRTUAL_KEYBOARD(&keyboard_id);
X
X  /* Set the beginning row position */
X  if (choice == 0)        choice = (num_items-6);
X  if ((choice+6) > num_items) choice = (num_items-6);
X
X  choicelen =  strlen(argv`5Bchoice+5`5D);
X  SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &choicelen, &SMG$M_REVE
VRSE);
X
X  do
X  `7B SMG$SET_CURSOR_ABS(&display_id, &choice, &2);
X    SMG$READ_KEYSTROKE(&keyboard_id, &keystroke);
X    switch (keystroke)
X    `7Bcase SMG$K_TRM_LEFT:case SMG$K_TRM_UP:        /*Left Arrow or Up Arro
Vw */
X       choicelen =  strlen(argv`5Bchoice+5`5D) - 1;
X       SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &1, &SMG$M_BOLD);
X       SMG$CHANGE_RENDITION(&display_id, &choice, &3, &1, &choicelen, &SMG$M
V_NORMAL);
X       --choice;
X       if (choice == 0) choice = (num_items-6);
X       choicelen =  strlen(argv`5Bchoice+5`5D);
X       SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &choicelen, &SMG$M
V_REVERSE);
X       break;
X     case SMG$K_TRM_RIGHT:case SMG$K_TRM_DOWN:   /*Right Arrow or Down Arrow
V or SpaceBar */
X       choicelen = strlen(argv`5Bchoice+5`5D) - 1;
X       SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &1, &SMG$M_BOLD);
X       SMG$CHANGE_RENDITION(&display_id, &choice, &3, &1, &choicelen, &SMG$M
V_NORMAL);
X       ++choice;
X       if (choice == ((num_items-6) + 1)) choice = 1;
X       choicelen =  strlen(argv`5Bchoice+5`5D);
X       SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &choicelen, &SMG$M
V_REVERSE);
X       break;
X     case SMG$K_TRM_CR:                /* Carriage Return */
X       break;
X     case SMG$K_TRM_CTRLR:             /* Control R       */
X       SMG$REPAINT_SCREEN(&pull_down);
X       break;
X     case SMG$K_TRM_CTRLW:             /* Control W       */
X       SMG$REPAINT_SCREEN(&pull_down);
X       break;
X     default:   /*Check for First letter of an entry */
X       choicelen =  strlen(argv`5Bchoice+5`5D) - 1;
X       SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &1, &SMG$M_BOLD);
X       SMG$CHANGE_RENDITION(&display_id, &choice, &3, &1, &choicelen, &SMG$M
V_NORMAL);
X       startchoice = choice;
X       do
X         `7B++choice;
X          if (choice == ((num_items-6) + 1)) choice = 1;
X          if (choice == startchoice) break;
X         `7D
X       while (letlookup(argv`5Bchoice+5`5D, keystroke));
X       choicelen =  strlen(argv`5Bchoice+5`5D);
X       SMG$CHANGE_RENDITION(&display_id, &choice, &2, &1, &choicelen, &SMG$M
V_REVERSE);
X       break;
X    `7D
X  `7D
X  while (keystroke != SMG$K_TRM_CR); /* Carriage Return */
X
X  /* Remove defined SMG$*/
X  SMG$DELETE_VIRTUAL_DISPLAY(&display_id);
X  SMG$DELETE_VIRTUAL_KEYBOARD(&keyboard_id);
X
X  /* Convert the integer chosen to a string */
X  itoa(choice,schoice);
X
X  /* Now replace the symbol with their choice */
X  strcpy(symtext, argv`5B1`5D);
X  symbol.dsc$w_length = strlen(argv`5B1`5D);
X
X  strcpy(lchoicetext, schoice);
X  lchoice.dsc$w_length = strlen(schoice);
X
X  LIB$SET_SYMBOL(&symbol, &lchoice);
X  exit(0);
X`7D
X
X/* Letlookup: Look at 1st letter of menu item and compare with keystroke */
Xletlookup(char *item, int key)
X`7B char line`5B80`5D;
X  strncpy(line, item, 80);
X  if ((line`5B0`5D == key) `7C`7C (toupper(line`5B0`5D) == key) `7C`7C (tolo
Vwer(line`5B0`5D) == key))
X    return 0;
X  else
X    return 1;
X`7D
X
X/* itoa: convert int choice to characters in schoice */
Xitoa(int n, char s`5B`5D)
X`7B
X  int cnt;
X  cnt = 0;
X  do                          /* generate digits in reverse order */
X  `7B s`5Bcnt++`5D = n % 10 + '0';`7D /* get next digit                   */
X  while ((n /= 10) > 0);      /* delete it                        */
X  s`5Bcnt`5D = '\0';
X  reverse(s);
X`7D
X
X/* Reverse a char array */
Xreverse(char s`5B`5D)
X`7B
X  int c,i,j;
X
X  for (i = 0, j = strlen(s)-1; i < j; i++, j--)
X  `7B  c = s`5Bi`5D;
X     s`5Bi`5D = s`5Bj`5D;
X     s`5Bj`5D = c;
X  `7D
X`7D
$ CALL UNPACK VMENU.C;9 1045426766
$ create 'f'
X$VMenu :== $TOOLS_SRC:`5BVmenu`5DVmenu.exe
X$! Arg 1 is a DCL Symbol
X$! Arg 2 is the row    `20
X$! Arg 3 is the column `20
X$! Arg 4 is the optional menu width (If 0, it is calculated)
X$! Arg 5 is the optional menu title (If no title is desired, put "")
X$! Arg 6 - .... are the menu items
X$MAINMENU:
X$ Define/nolog sys$input sys$command
X$ VMenu M$C 7 30 0 -
X  "A big title line" -`20
X  "1. User disk"  -
X  "2. system disk" -
X  "3. exit"  -
X  "1. User disk"  -
X  "system disk" -
X  "exit" `20
X$ If M$C .eqs. "1" then write sys$output "1"
X$ If M$C .eqs. "2" then goto vtest
X$ If M$C .eqs. "6" Then Exit
X$ Read /prompt="Press return to continue...." sys$input temp
X$ Goto MainMenu
X$!
X$vtest:
X$ @vtest_1.com
X$ write sys$output "Back..."
X$ Goto MainMenu
X$ exit
$ CALL UNPACK VTEST.COM;25 891685863
$ v=f$verify(v)
$ EXIT


