home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / VISIONS.ZIP / DEMOLIST.C < prev    next >
Text File  |  1990-05-18  |  29KB  |  738 lines

  1. /*------------------------- DEMOLIST.C -------------------------*/
  2. /*                                                              */
  3. /*  This file contains the VISIONS LIBRARY LIST DEMO software.  */
  4. /*                                                              */
  5. /*         Copyright 1990 Dan Vogel & David Bernazzani          */
  6. /*                                                              */
  7. /*   Date        Initials        Comments                       */
  8. /*                                                              */
  9. /*  03/07/90       DCV        Initial Release 0.00              */
  10. /*--------------------------------------------------------------*/
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <malloc.h>
  15. #include <ctype.h>
  16. #include "USERLIST.H"
  17. #include "USERWIND.H"
  18. #include "USERFORM.H"
  19. #include "DEMOPROT.H"
  20.  
  21. static char *cnotice="VISIONS Copyright 1990 Dan Vogel & David Bernazzani";
  22.  
  23. /*--------------------------------------------------------------*/
  24.  
  25.  
  26.  
  27.                 /* Window Commands */
  28. #define WIND_INIT    0      /* Create a window. */
  29. #define WIND_UPDATE  1      /* Update the window displayed data. */
  30. #define WIND_DEL     2      /* Close the window. */
  31.  
  32. /*-----------------------------------------------------------------*/
  33. /*                           Run_List                              */
  34. /*          This is the list library demonstration code.           */
  35. /*                                                                 */
  36. /*  The VISIONS list library demonstration code below is set up    */
  37. /* to allow the user to interactively create a displayed list      */
  38. /* of up to 10 string items.  These items may be added, appended,  */
  39. /* deleted, searched, and sorted.  Cursor highlights of the list   */
  40. /* items are controlled by the arrow keys, Ins, and Del.  This     */
  41. /* allows the list functions to be invoked by the user with visual */
  42. /* feedback.  Implementing this mechanism on the screen requires   */
  43. /* the following visual 'areas': a command window, a list display  */
  44. /* window, a string entry form, a list length counter window, a    */
  45. /* response window and an introductory explanation window.         */
  46. /*   Separate windows are set up for each of these functions, and  */
  47. /* then a keystroke driven execution loop is entered to allow the  */
  48. /* user interaction.                                               */
  49. /*   More complex list examples are given in the comments of this  */
  50. /* code.                                                           */
  51. /*   WARNING - Most error checking has been removed to make the    */
  52. /* code easier to read.  Users of VISIONS should check for error   */
  53. /* returns!                                                        */
  54. /*-----------------------------------------------------------------*/
  55. int Run_List()
  56. {
  57.    WINDOW_HEAD *clear_window;      /* Window to clear screen. */
  58.    WINDOW_HEAD *command_window;    /* Commands available window. */
  59.    WINDOW_HEAD *list_window;       /* List display. */
  60.    WINDOW_HEAD *length_window;     /* List length display. */
  61.    WINDOW_HEAD *response_window;   /* Error response screen. */
  62.    LIST_HEAD *demo_list;           /* Demonstration list pointer. */
  63.    LIST_LINK *list_cursor;         /* Screen list cursor pointer. */
  64.    LIST_LINK *tmp_cursor;          /* Temporary cursor holder. */
  65.    unsigned char *item_pointer;    /* List item pointer. */
  66.    int list_num;                   /* Number of items in the list. */
  67.    int key;                        /* User input holder. */
  68.    int status=0;
  69.  
  70.    /*-------------------------------------------*/
  71.    /* Create a window just to clear the screen. */
  72.    /*-------------------------------------------*/
  73.    DefineWindow(&clear_window, 1, 1, 24, 80,
  74.       TEXT_BLACK, TEXT_WHITE, "", NOBORDER, FALSE, FALSE, TRUE);
  75.    DisplayWindow(clear_window);
  76.  
  77.    /*-------------------------------------------*/ 
  78.    /* Tell the user what this routine is about. */
  79.    /*-------------------------------------------*/
  80.    List_Intro();
  81.  
  82.    /*-------------------------------*/
  83.    /* Display the list of commands. */
  84.    /*-------------------------------*/
  85.    Command_Wind(&command_window, WIND_INIT);
  86.  
  87.    /*---------------------------------------------*/
  88.    /* Initialize the list and the display window. */
  89.    /*---------------------------------------------*/
  90.    DefineList(&demo_list,*CompareString,*ReleaseString,*CopyString);
  91.    list_cursor = NULL;
  92.    Display_Wind(&list_window, WIND_INIT, demo_list, list_cursor);
  93.  
  94.    /*------------------------------------*/
  95.    /* Initialize the list length window. */
  96.    /*------------------------------------*/
  97.    Length_Wind(&length_window, WIND_INIT, demo_list);
  98.  
  99.    /*-----------------------------------------*/
  100.    /* Initialize the command response window. */
  101.    /*-----------------------------------------*/
  102.    Response_Wind(&response_window, WIND_INIT, "");
  103.  
  104.  
  105.    /*-------------------------------------------------------*/
  106.    /* This is the user command interpreter loop.  The       */
  107.    /* basic structure is similar to most interpreters,      */
  108.    /* a token input followed by a switch or dispatch        */
  109.    /* command that actually handles the different commands. */
  110.    /*-------------------------------------------------------*/
  111.    while (((char)(key = GetKey())) != ESC)  /* Until user strikes ESC */
  112.    {
  113.       /*---------------------------------*/
  114.       /* Clear the last response window. */
  115.       /*---------------------------------*/
  116.       Response_Wind(&response_window, WIND_UPDATE, "");
  117.  
  118.       /*--------------------------*/
  119.       /* Interpret the keystroke. */
  120.       /*--------------------------*/
  121.       switch (key)
  122.       {
  123.       case HOME:  /* Move cursor to top of displayed list. */
  124.          ListTop(demo_list, &list_cursor);
  125.          break;
  126.       case END:   /* Move cursor to bottom of displayed list. */
  127.          ListBottom(demo_list,&list_cursor);
  128.          break;
  129.       case UP:    /* Move cursor up one position on list. */
  130.          ListLast(list_cursor,&tmp_cursor);
  131.          if (tmp_cursor != NULL)
  132.             list_cursor = tmp_cursor;
  133.          break;
  134.       case DOWN:  /* Move cursor down one position on displayed list. */
  135.          ListNext(list_cursor,&tmp_cursor);
  136.          if (tmp_cursor != NULL)
  137.             list_cursor = tmp_cursor;
  138.          break;
  139.       case INS:   /* Add a list item before the current cursor. */
  140.          if (CountList(demo_list) >= 10)   /* Maximum list length is 10. */
  141.             Response_Wind(&response_window, WIND_UPDATE, 
  142.                 "List is already full.");
  143.          else
  144.          {
  145.             if (EnterListItem(&item_pointer) != -1)
  146.             {     /* If user enters an item */
  147.                status = AddToList(demo_list, list_cursor, item_pointer);
  148.                if (status != 0)   /* Handle error here by deleting item! */
  149.                {
  150.                   free(item_pointer);   /* Release storage and tell user. */
  151.                   Response_Wind(&response_window, WIND_UPDATE, 
  152.                       "Unable to insert new list item.");
  153.                   status = 0;
  154.                }
  155.                else  /* If all went well, set cursor to new item. */
  156.                   FindInList(demo_list, item_pointer, &list_cursor);
  157.             }
  158.          }
  159.          break;
  160.       case DEL:   /* Delete the current list item. */
  161.          if (GetListItem(list_cursor, &item_pointer) == 0)
  162.          {     /* If the cursor was good, set up new cursor, then delete. */
  163.             ListNext(list_cursor,&tmp_cursor);
  164.             if (tmp_cursor != NULL)
  165.                list_cursor = tmp_cursor;
  166.             else
  167.                ListLast(list_cursor,&list_cursor);
  168.             if (DeleteFromList(demo_list, item_pointer) != 0)
  169.                Response_Wind(&response_window, WIND_UPDATE, 
  170.                    "Unable to delete list item.");
  171.          }
  172.          else
  173.             Response_Wind(&response_window, WIND_UPDATE, 
  174.                "Cursor does not point to valid list link.");
  175.          break;
  176.       case 'A':   /* Append an item to the list. */
  177.       case 'a':
  178.          if (CountList(demo_list) >= 10)   /* Check Max list length. */
  179.             Response_Wind(&response_window, WIND_UPDATE, 
  180.                "List is already full.");
  181.          else
  182.          {
  183.             if (EnterListItem(&item_pointer) != -1)
  184.             {    /* If user enters an item */
  185.                status = AppendToList(demo_list, item_pointer);
  186.                if (status != 0)   /* Handle error here by deleting item! */
  187.                {
  188.                   free(item_pointer);   /* Release storage and tell user. */
  189.                   Response_Wind(&response_window, WIND_UPDATE, 
  190.                       "Unable to append new list item.");
  191.                   status = 0;
  192.                }
  193.             }
  194.             ListBottom(demo_list,&list_cursor); /* Set cursor to new item. */
  195.          }
  196.          break;
  197.       case 'S':   /* Sort the list and redisplay it. */
  198.       case 's':
  199.          SortList(demo_list,*CompareString);
  200.          ListTop(demo_list, &list_cursor);   /* Set cursor to list top. */
  201.          break;
  202.       case 'J':   /* Jump to the nth item in the list. */
  203.       case 'j':
  204.          if (GetListItemNumber(&list_num) >= 0)   /* Get # to jump to. */
  205.          {
  206.             if (list_num >= 0)
  207.             {
  208.                if (ListNth(demo_list, list_num, &tmp_cursor) != 0)
  209.                   Response_Wind(&response_window, WIND_UPDATE,
  210.                       "Invalid list item number.");
  211.                else
  212.                   list_cursor = tmp_cursor;
  213.             }
  214.          }
  215.          break;
  216.       }
  217.  
  218.       /*-----------------------------*/
  219.       /* Update the display windows. */
  220.       /*-----------------------------*/
  221.       Display_Wind(&list_window,WIND_UPDATE,demo_list,list_cursor);
  222.       Length_Wind(&length_window, WIND_UPDATE, demo_list);
  223.    }
  224.  
  225.    /*----------------------------------*/
  226.    /* Delete the list and the windows. */
  227.    /*----------------------------------*/
  228.    Command_Wind(&command_window, WIND_DEL);
  229.    Display_Wind(&list_window,WIND_DEL,demo_list,list_cursor);
  230.    Length_Wind(&length_window, WIND_DEL, demo_list);
  231.    Response_Wind(&response_window, WIND_DEL, "");
  232.    DeleteList(demo_list);
  233.  
  234. exit:
  235.    RemoveWindow(clear_window);
  236.    DeleteWindow(clear_window);
  237.    return(status);
  238. }
  239.  
  240.  
  241.  
  242.  
  243.  
  244. /*--------------------------------------------------------*/
  245. /*                      CopyString                        */
  246. /* This is the simple list example version of the display */
  247. /* item routine.  Since the simple example keeps lists    */
  248. /* of character strings, this routine just copies the     */
  249. /* list character string over into an output buffer for   */
  250. /* display.  No other formatting takes place.             */
  251. /*   If the list were a structure, for example:           */
  252. /*      struct employee_info                              */
  253. /*      {                                                 */
  254. /*         char first_name[10];                           */
  255. /*         char last_name[10];                            */
  256. /*         char ss_number[12];                            */
  257. /*      }                                                 */
  258. /*  then this routine might look more like:               */
  259. /*      int Format_Employee(instr,outstr)                 */
  260. /*      unsigned char *instr, *outstr;                    */
  261. /*      {                                                 */
  262. /*         struct employee_info *employee;                */
  263. /*                                                        */
  264. /*         employee = (struct employee_info *) instr;     */
  265. /*         strcpy(outstr,employee->first_name);           */
  266. /*         strcat(outstr," ");                            */
  267. /*         strcat(outstr,employee->last_name);            */
  268. /*         strcat(outstr,"   ");                          */
  269. /*         strcat(outstr,employee->ss_number);            */
  270. /*         return(0);                                     */
  271. /*      }                                                 */
  272. /*                                                        */
  273. /*  Note that you are not tied to a single display format,*/
  274. /* this is just the routine used by DisplayList.  You may */
  275. /* create different display routines for uses at different*/
  276. /* times, and call them directly instead of through the   */
  277. /* library.                                               */
  278. /*--------------------------------------------------------*/
  279. int CopyString(instr, outstr)
  280. unsigned char *instr, *outstr;
  281. {
  282.    strcpy(outstr,instr);
  283.    return(0);
  284. }
  285.  
  286.  
  287.  
  288. /*------------------------------------------------------------*/
  289. /*                      CompareString                         */
  290. /* This is the simple list example version of the item        */
  291. /* compare routine.  Again, as the items here are simple      */
  292. /* character strings, we can use strcmp to do the comparison. */
  293. /*   A more complex case such as the example given in         */
  294. /* CopyString would require comparisons of all the items      */
  295. /* within the structure.                                      */
  296. /*------------------------------------------------------------*/
  297. int CompareString(instr, outstr)
  298. unsigned char *instr, *outstr;
  299. {
  300.    return(strcmp(instr,outstr));
  301. }
  302.  
  303.  
  304.  
  305. /*-------------------------------------------------------*/
  306. /*                     ReleaseString                     */
  307. /* This is the simple list example version of the item   */
  308. /* delete routine.  Since we are using character strings */
  309. /* allocated from the heap, we just 'free' them.  If we  */
  310. /* were using predefined variables, like X="123", we     */
  311. /* would not need this routine at all!                   */
  312. /*  The CopyString example of the use of a structure     */
  313. /* would not change this routine.                        */
  314. /*-------------------------------------------------------*/
  315. int ReleaseString(delstr)
  316. unsigned char *delstr;
  317. {
  318.    return(free(delstr));
  319. }
  320.  
  321.  
  322.  
  323.  
  324. /*---------------------------------------------------*/
  325. /*                                                   */
  326. /*   The remainder of the file consists primarily of */
  327. /* screen handling routines.  While these may be of  */
  328. /* interest as examples of forms and windows library */
  329. /* use, they are not directly related to the list    */
  330. /* library demonstration.                            */
  331. /*                                                   */
  332. /*---------------------------------------------------*/
  333.  
  334.  
  335. /*-----------------------------------------------*/
  336. /*                List_Intro                     */
  337. /* Introduce the user to this demonstration,     */
  338. /* explaining the purpose and what is happening. */
  339. /*-----------------------------------------------*/
  340. int List_Intro()
  341. {
  342.    WINDOW_HEAD *intro_window;
  343.  
  344.    DefineWindow(&intro_window, 1, 1, 24, 80,
  345.         TEXT_BLUE, TEXT_WHITE, "VISIONS List Demonstration Introduction",
  346.         SINGLEBORDER, FALSE, FALSE, TRUE);
  347.    DisplayWindow(intro_window);
  348.    WindMesg(9,7,
  349.     "   The VISIONS list library demonstration is intended to introduce ");
  350.    WindMesg(10,7,
  351.     " the user to the list library concepts and functions through the ");
  352.    WindMesg(11,7,
  353.     " use of a simple interactive example.  This example takes the form ");
  354.    WindMesg(12,7,
  355.     " of an interactive manipulation of a list of up to ten string ");
  356.    WindMesg(13,7,
  357.     " elements.  Each action taken by the user causes a list manipulation ");
  358.    WindMesg(14,7,
  359.     " to be performed by one or more VISIONS list library routines.  This ");
  360.    WindMesg(15,7,
  361.     " is displayed in the list display window.  The source code used to ");
  362.    WindMesg(16,7,
  363.     " create this demonstration is supplied with the executable.  More ");
  364.    WindMesg(17,7,
  365.     " complex examples of list management are given in comments in the ");
  366.    WindMesg(18,7," source code.");
  367.  
  368.    WindMesg(24,28,"Hit any key to continue.");
  369.  
  370.    GetKey();   /* Force a key strike by the user. */
  371.  
  372.    RemoveWindow(intro_window);   /* And destroy the window. */
  373.    DeleteWindow(intro_window);
  374.  
  375.    return(0);
  376. }
  377.  
  378.  
  379.  
  380. /*-------------------------------------------*/
  381. /*              Command_Wind                 */
  382. /* Display the command set that the user has */
  383. /* available for the interactive list demo.  */
  384. /* Use the passed window pointer for display.*/
  385. /*-------------------------------------------*/
  386.  
  387.                  /* Command Window Parameters */
  388. #define COMMAND_ROW     3
  389. #define COMMAND_COL     36
  390. #define COMMAND_WIDTH   43
  391. #define COMMAND_HEIGHT  13
  392. #define COMMAND_BKCOL   TEXT_RED
  393. #define COMMAND_TXTCOL  TEXT_BWHITE
  394. #define COMMAND_TITLE   "List Editing Commands"
  395. #define COMMAND_BORDER  SINGLEBORDER
  396.  
  397. int Command_Wind(command_window, cmd)
  398. WINDOW_HEAD **command_window;    /* The window pointer to use. */
  399. int cmd;                         /* The window command (INIT, DELete. */
  400. {
  401.  
  402.    switch(cmd)
  403.    {
  404.    case WIND_INIT:
  405.       DefineWindow(command_window, COMMAND_ROW, COMMAND_COL, 
  406.         COMMAND_HEIGHT, COMMAND_WIDTH,
  407.         COMMAND_BKCOL, COMMAND_TXTCOL, COMMAND_TITLE,
  408.         COMMAND_BORDER, TRUE, TRUE, TRUE);
  409.       DisplayWindow(*command_window);
  410.       WindMesg(4,3,"HOME - Move cursor to list top");
  411.       WindMesg(5,3,"END  - Move cursor to list bottom");
  412.       WindMesg(6,3,"UP   - Move cursor up one item");
  413.       WindMesg(7,3,"DOWN - Move Cursor down one item");
  414.       WindMesg(8,3,"INS  - Insert new item into list");
  415.       WindMesg(9,3,"DEL  - Delete current item from list");
  416.       WindMesg(10,3,"A   - Append new item to list");
  417.       WindMesg(11,3,"S   - Sort list and redisplay");
  418.       WindMesg(12,3,"J   - Move cursor to numbered list item");
  419.       break;
  420.    case WIND_DEL:
  421.       RemoveWindow(*command_window);
  422.       DeleteWindow(*command_window);
  423.       break;
  424.    }
  425.  
  426.    return(0);
  427. }
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434. /*--------------------------------------------------------------*/
  435. /*                       Display_Wind                           */
  436. /*   The following window is used to display the list contents. */
  437. /* This could normally be done much more simply by calling the  */
  438. /* DisplayList routine.  This would only display the list       */
  439. /* until a key was struck however.  Therefore the routine       */
  440. /* below was written to leave the list display up on the screen */ 
  441. /* during the entire demonstration of the list library.         */
  442. /*--------------------------------------------------------------*/
  443.  
  444.                  /* List Display Window Parameters */
  445. #define DISPLAY_ROW     5
  446. #define DISPLAY_COL     3
  447. #define DISPLAY_WIDTH   25
  448. #define DISPLAY_HEIGHT  14
  449. #define DISPLAY_BKCOL   TEXT_BLUE
  450. #define DISPLAY_TXTCOL  TEXT_WHITE
  451. #define DISPLAY_HIBKCOL   TEXT_BLUE
  452. #define DISPLAY_HITXTCOL  TEXT_BWHITE
  453. #define DISPLAY_TITLE   "List Display"
  454. #define DISPLAY_BORDER  DOUBLEBORDER
  455.  
  456. int Display_Wind(list_window, cmd, demo_list, list_cursor)
  457. WINDOW_HEAD **list_window;     /* The window pointer to use. */
  458. LIST_HEAD *demo_list;          /* The list to display.       */
  459. LIST_LINK *list_cursor;        /* The list item to highlight. */
  460. int cmd;                       /* The window display command. */
  461. {
  462.    LIST_LINK *list_travel;
  463.    char buffer[81];
  464.    int disp_row=0;
  465.  
  466.    switch(cmd)
  467.    {
  468.    case WIND_INIT:      /* Initially define and display the window. */
  469.       DefineWindow(list_window, DISPLAY_ROW, DISPLAY_COL, 
  470.         DISPLAY_HEIGHT, DISPLAY_WIDTH,
  471.         DISPLAY_BKCOL, DISPLAY_TXTCOL, DISPLAY_TITLE,
  472.         DISPLAY_BORDER, TRUE, TRUE, TRUE);
  473.       DisplayWindow(*list_window);
  474.    case WIND_UPDATE:    /* Redisplay the window, with cursor color inverted.*/
  475.       SetWindowPtr(*list_window);
  476.       ListTop(demo_list, &list_travel);
  477.       while (disp_row++ < 10)       /* Display the list of up to 10 items. */
  478.       {
  479.          if (list_travel == NULL)
  480.             strcpy(buffer,"     ");
  481.          else
  482.             DisplayListItem(demo_list, list_travel, buffer);
  483.          if (list_travel == list_cursor)      /* Highlighted item? */
  484.          {
  485.             SetBkColor(DISPLAY_HIBKCOL);
  486.             SetTextColor(DISPLAY_HITXTCOL);
  487.          }
  488.          while (strlen(buffer) < DISPLAY_WIDTH - 4)
  489.             strcat(buffer," ");
  490.          WindMesg(disp_row + 3, 3, buffer);
  491.          if (list_travel == list_cursor)   /* Reset colors after highlight. */
  492.          {
  493.             SetBkColor(DISPLAY_BKCOL);
  494.             SetTextColor(DISPLAY_TXTCOL);
  495.          }
  496.          ListNext(list_travel,&list_travel);
  497.       }
  498.       break;
  499.    case WIND_DEL:    /* Finally shut down the window. */
  500.       RemoveWindow(*list_window);
  501.       DeleteWindow(*list_window);
  502.       break;
  503.    }
  504.  
  505.    return(0);
  506. }
  507.  
  508.  
  509.  
  510. /*---------------------------------------------*/
  511. /*                Length_Wind                  */
  512. /* This creates a small window used to display */
  513. /* the number of items in the current list.    */
  514. /*---------------------------------------------*/
  515.  
  516.               /* List Length Window Parameters */
  517. #define LENGTH_ROW     3
  518. #define LENGTH_COL     3
  519. #define LENGTH_WIDTH   25
  520. #define LENGTH_HEIGHT  2
  521. #define LENGTH_BKCOL   TEXT_GREEN
  522. #define LENGTH_TXTCOL  TEXT_BWHITE
  523. #define LENGTH_TITLE   "Number of Items in List"
  524. #define LENGTH_BORDER  NOBORDER
  525.  
  526. int Length_Wind(length_window, cmd, demo_list)
  527. WINDOW_HEAD **length_window;    /* The window pointer to use. */
  528. LIST_HEAD *demo_list;           /* The list to count. */
  529. int cmd;                        /* The window command. */
  530. {
  531.    int length;
  532.    char buffer[20];
  533.  
  534.    switch(cmd)
  535.    {
  536.    case WIND_INIT:   /* Define and display the window. */
  537.       DefineWindow(length_window, LENGTH_ROW, LENGTH_COL, 
  538.         LENGTH_HEIGHT, LENGTH_WIDTH,
  539.         LENGTH_BKCOL, LENGTH_TXTCOL, LENGTH_TITLE,
  540.         LENGTH_BORDER, TRUE, TRUE, TRUE);
  541.       DisplayWindow(*length_window);
  542.    case WIND_UPDATE: /* Display the list length in the window. */
  543.       if ((length = CountList(demo_list)) <= 10)
  544.       {
  545.          sprintf(buffer,"%2.2d",length);
  546.          WindMesgPtr(*length_window,2,12,buffer);
  547.       }
  548.       break;
  549.    case WIND_DEL:    /* Destroy the window. */
  550.       RemoveWindow(*length_window);
  551.       DeleteWindow(*length_window);
  552.       break;
  553.    }
  554.  
  555.    return(0);
  556. }
  557.  
  558.  
  559.  
  560.  
  561. /*------------------------------------------------------*/
  562. /*                  Response_Wind                       */
  563. /* The window created and maintained by this routine is */
  564. /* used for interaction with the user.  It's primary    */
  565. /* function is to display single line error messages    */
  566. /* related to an illegal command made by the user.      */
  567. /*------------------------------------------------------*/
  568.  
  569.                  /* Command Response Window Parameters */
  570. #define RESPONSE_ROW     25
  571. #define RESPONSE_COL     1
  572. #define RESPONSE_WIDTH   80
  573. #define RESPONSE_HEIGHT  1
  574. #define RESPONSE_BKCOL   TEXT_WHITE
  575. #define RESPONSE_TXTCOL  TEXT_RED
  576. #define RESPONSE_TITLE   ""
  577. #define RESPONSE_BORDER  NOBORDER
  578.  
  579. int Response_Wind(response_window, cmd, msg)
  580. WINDOW_HEAD **response_window;   /* The window pointer to use. */
  581. int cmd;                       /* The window command, INIT, DEL, UPDATE. */
  582. char *msg;                     /* Message to display in the window. */
  583. {
  584.    char buffer[81];
  585.  
  586.    switch(cmd)
  587.    {
  588.    case WIND_INIT:   /* Define and display the window. */
  589.       DefineWindow(response_window, RESPONSE_ROW, RESPONSE_COL, 
  590.         RESPONSE_HEIGHT, RESPONSE_WIDTH,
  591.         RESPONSE_BKCOL, RESPONSE_TXTCOL, RESPONSE_TITLE,
  592.         RESPONSE_BORDER, TRUE, TRUE, TRUE);
  593.       DisplayWindow(*response_window);
  594.       break;
  595.    case WIND_UPDATE:   /* Display the message, or clear the message line. */
  596.       if ((msg == NULL) || (strlen(msg) == 0))
  597.          strcpy(buffer," ");
  598.       else
  599.       {
  600.          strncpy(buffer,msg,RESPONSE_WIDTH-1);
  601.          buffer[RESPONSE_WIDTH-2] = (char)NULL;
  602.       }
  603.       while (strlen(buffer) < RESPONSE_WIDTH-2)
  604.          strcat(buffer," ");
  605.       WindMesgPtr(*response_window,1,2,buffer);
  606.       break;
  607.    case WIND_DEL:     /* Destroy the window. */
  608.       RemoveWindow(*response_window);
  609.       DeleteWindow(*response_window);
  610.       break;
  611.    }
  612.  
  613.    return(0);
  614. }
  615.  
  616.  
  617.  
  618.  
  619. /*--------------------------------------------------*/
  620. /*                 EnterListItem                    */
  621. /* This routine generates a form used to allow the  */
  622. /* operator to enter a text string that will become */
  623. /* a list item.  This is a good short example of    */
  624. /* a form being used.                               */
  625. /*--------------------------------------------------*/
  626. int EnterListItem(item_pointer)
  627. unsigned char **item_pointer;   /* Returned pointer to string entered. */
  628. {
  629.    FORM_HEAD *new_form;
  630.    FORM_FIELD *field_ptr;
  631.    int status=0;
  632.  
  633.    /*---------------------------------------*/
  634.    /* Allocate memory for the string entry. */
  635.    /*---------------------------------------*/
  636.    *item_pointer = (unsigned char *)malloc(26*sizeof(char));
  637.    strcpy(*item_pointer,"");
  638.  
  639.    /*-------------------------------*/
  640.    /* Create the string entry form. */
  641.    /*-------------------------------*/
  642.    DefineForm(&new_form,12,15,6,25,SINGLEBORDER,
  643.         TEXT_BROWN,TEXT_BWHITE,"LIST ITEM ENTRY");
  644.    AddToForm(new_form, NULL, &field_ptr);
  645.    AddToPrompt(field_ptr, 4, 2, 6, TEXT_BROWN,TEXT_BWHITE,
  646.         TEXT_BWHITE,TEXT_BROWN,"Item: ");
  647.    AddToText(field_ptr, 5, 2, 21, TEXT_BLACK,TEXT_WHITE,
  648.         TEXT_WHITE,TEXT_BLACK,*item_pointer);
  649.  
  650.    /*-------------------------------------*/
  651.    /* Execute the form to get user input. */
  652.    /*-------------------------------------*/
  653.    status = FormEntry(new_form);
  654.  
  655.    /*------------------------------------------------------*/
  656.    /* Release the memory if the user aborted string entry. */
  657.    /*------------------------------------------------------*/
  658.    if (status != 0)
  659.       free(*item_pointer);
  660.  
  661.    /*------------------*/
  662.    /* Delete the form. */
  663.    /*------------------*/
  664.    DeleteForm(new_form);
  665.  
  666.    /*---------------------------*/
  667.    /* Tell the caller if form   */
  668.    /* was aborted or completed. */
  669.    /*---------------------------*/
  670.    return(status);
  671. }
  672.  
  673.  
  674.  
  675. /*--------------------------------------------------*/
  676. /*                GetListItemNumber                 */
  677. /* This routine generates a form used to allow the  */
  678. /* operator to enter a number of the list item to   */
  679. /* be selected.  This is a good short example of    */
  680. /* a form being used.                               */
  681. /*--------------------------------------------------*/
  682.  
  683. int GetListItemNumber(list_num)
  684. int *list_num;             /* Pointer to integer to return number in. */
  685. {
  686.    FORM_HEAD *new_form;
  687.    FORM_FIELD *field_ptr;
  688.    char string_ret[3];     /* Temporary string for number entry. */
  689.    int status=0;
  690.  
  691.    strcpy(string_ret,"");
  692.    *list_num = 0;
  693.  
  694.    /*------------------------*/
  695.    /* Create the entry form. */
  696.    /*------------------------*/
  697.    DefineForm(&new_form,12,15,5,25,SINGLEBORDER,
  698.         TEXT_BROWN,TEXT_BWHITE,"LIST ITEM NUMBER");
  699.    AddToForm(new_form, *IntOnly, &field_ptr);
  700.    AddToPrompt(field_ptr, 4, 2, 8, TEXT_BROWN,TEXT_BWHITE,
  701.         TEXT_BWHITE,TEXT_BROWN,"Number: ");
  702.    AddToText(field_ptr, 4, 11, 2, TEXT_BLACK,TEXT_WHITE,
  703.         TEXT_WHITE,TEXT_BLACK,string_ret);
  704.  
  705.    /*-----------------------*/
  706.    /* Now execute the form. */
  707.    /*-----------------------*/
  708.    status = FormEntry(new_form);
  709.  
  710.    /*-+--------------------------*/
  711.    /* Release the form's memory. */
  712.    /*----------------------------*/
  713.    DeleteForm(new_form);
  714.  
  715.    /*--------------------------------------*/
  716.    /* Convert the received string into     */
  717.    /* an integer, if form was not aborted. */
  718.    /*--------------------------------------*/
  719.    if (status != -1)
  720.    {
  721.       if (isdigit(string_ret[0]) != 0)
  722.          *list_num = (int)(string_ret[0] - '0');
  723.       if (isdigit(string_ret[1]) != 0)
  724.          *list_num = (*list_num * 10) + (int)(string_ret[1] - '0');
  725.       *list_num = *list_num - 1;
  726.       if (*list_num < 0)
  727.          *list_num = 0;
  728.       if (*list_num > 9)
  729.          *list_num = 9;
  730.    }
  731.  
  732.    /*---------------------------*/
  733.    /* Tell the caller if form   */
  734.    /* was aborted or completed. */
  735.    /*---------------------------*/
  736.    return(status);
  737. }
  738.