home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / pocketbk / developmen / longlist / VARRAY.TXT < prev   
Text File  |  1994-04-13  |  8KB  |  220 lines

  1. Long choice lists in OPL
  2.  
  3. Choice lists in OPL dialogs are limited to a maximum of 255 
  4. items. For some applications this may be considered a problem 
  5. and there is a mechanism by which this limit may be 
  6. circumvented. Consider the following from the SIBO C SDK 
  7. Introduction to HWIF:
  8.  
  9.     Longer choice lists
  10.  
  11. In some cases, the list of choices presented in a particular 
  12. choice list may be too long for a choice list to be conveniently 
  13. defined simply by one call to
  14.  
  15. uAddChoiceList.
  16.  
  17. The three functions uBeginDCL, uGrowDCL, and uAddDCL exist to help 
  18. out with these so-called dynamic choice lists (the name reflects 
  19. the fact that the contents of the choice list are built up over a 
  20. few lines of code, rather than just being defined statically; in 
  21. some cases, the contents in the list may change between 
  22. different invocations of the dialog, to reflect changing run-time 
  23. circumstances).
  24.  
  25. For example, the following routine builds up a choice list 
  26. whose contents are the twelve month names:
  27.  
  28. LOCAL_C INT AddMonthChoiceList(UWORD *pmonno)
  29.     {
  30.     H_DI_CHOICE ch;
  31.     TEXT mon[32];
  32.     INT i;
  33.  
  34.     if (uBeginDCL(&ch))
  35.         return(-1);            /* report failure to caller */
  36.     for (i=0; i<12; i++)
  37.         {
  38.         p_nmmon(&mon[0],i);
  39.         if (uGrowDCL(&ch,&mon[0]))
  40.             return(-1);        /* report failure to caller */
  41.         }
  42.     return(uAddDCL("Month",pmonno,&ch));
  43.     }
  44.  
  45. Alternatively, the function hSetVarrayInChlist can be used to 
  46. build up a choice list, especially if the list might contain more 
  47. than 255 items.
  48.  
  49.  
  50.  
  51. For example, by modifying the above code, the same effect can 
  52. be achieved as shown below:
  53.  
  54. #define C_VASTR 6
  55. #define O_VA_APPEND 7
  56. #define OLIB_CAT 1
  57.  
  58. LOCAL_C INT AddMonthChoiceList(INT item_no,INT *pmonno)
  59.     {
  60.     UWORD used = 0;
  61.     VOID  *pvarray;
  62.     TEXT  mon[32];
  63.     INT   i;
  64.     
  65.     
  66.     if (uAddChoiceList("month",&used,NULL))
  67.         return(-1);            /* failure */
  68.     pvarray = p_new(OLIB_CAT,C_VASTR);
  69.     for (i = 0; i < 12; i++)
  70.         {
  71.         p_nmmon(&mon[0],i);
  72.         p_send3(pvarray,O_VA_APPEND,&mon[0]);
  73.         }
  74.     
  75. hSetVarrayInChlist(item_no,(*pmonno),pvarray):
  76.     }
  77.  
  78. Note that error handling in this code is incomplete.
  79.  
  80. It is entirely possible to emulate this fucntionality in an OPL 
  81. program and the two OPL programs which accompany this 
  82. documentation provide guidance on exactly how this may be 
  83. done. The OPL programs are called STRLIST.OPL and 
  84. FLATLIST.OPL and their names reflect a subtle variation in 
  85. the way they operate. The OPL code is extensively commented 
  86. and should be read with the following in mind. The basic 
  87. process is straightforward:
  88.  
  89. *    Create an array which contains the a variable number of 
  90.     records representing the data of our choice list. We use one 
  91.     of two subclasses of the OLIB class VAROOT: VASTR or 
  92.     VAFLAT. In the case of a VASTR array, our records are of 
  93.     variable length. In the case of a VAFLAT array, the records 
  94.     are of a fixed length. Both approaches have their 
  95.     advantages and disadvantages. Assuming they contain the 
  96.     same 'live' data, VASTR arrays use less memory than 
  97.     VAFLAT arrays. However, VAFLAT arrays can be 
  98.     navigated more swiftly than VASTR arrays - this is 
  99.     particularly noticeable when pressing <Tab> to pop-out 
  100.     the choice list while in a dialog. Consider the following 
  101.     (taken from the SIBO SDK OLIB Reference):
  102.  
  103.  
  104.  
  105.     Usage summary
  106.     
  107.     VAROOT and VAFIX are abstract classes. VAROOT defines a 
  108.     relatively large number of deferred methods in order to 
  109.     promote polymorphism between the directly usable classes.
  110.     
  111.     The VASTR class is used to create arrays of variable length 
  112.     text records, stored as zero terminated strings. The storage 
  113.     overhead per string is only one byte, so it is particularly 
  114.     suitable for storing short strings, of up to, say, several tens 
  115.     of bytes, or for strings with a wide variation in size (such as 
  116.     file names, which can be any length up to 128 bytes, but are 
  117.     usually much shorter). Since the whole array is stored in a 
  118.     single allocated cell, the VASTR class is most suitable for 
  119.     arrays that contain:
  120.         *    a small number of records
  121.         *    a moderately large, but fixed maximum, number
  122.             of records (for which the maximum capacity can
  123.             be allocated in advance)
  124.     Because of its suitability for storing file names, the VASTR 
  125.     class is used, for example, to store directory listings. In 
  126.     general, however, the VASTR class not particularly suitable for 
  127.     arrays which can dynamically grow to a very large size. 
  128.  
  129.     The resulting repeated calls to p_realloc are likely to cause 
  130.     heap fragmentation and seriously reduce the effective use 
  131.     of memory.
  132.  
  133.     The VAFLAT class is used to create arrays of fixed length 
  134.     records, where the whole array is stored in a single 
  135.     allocated cell. The preferred usage is as for the VASTR class.
  136.  
  137. *    Create a dialog which contains the desired components but 
  138.     don't run it yet. This is done using the dINIT "title", 
  139.     dCHOICE..., commands.
  140.  
  141. *    Call the O_WN_SET method of the DLGBOX class to alter 
  142.     the data elements used by the dCHOICE. This is clearly 
  143.     marked in the code. Consider the following excerpts (taken 
  144.     from the SIBO SDK Object Oriented Programming Guide):
  145.     
  146.     WN_SET    Set item by index
  147.  
  148.     VOID wn_set(INT index, VOID *par);
  149.  
  150.     Set one or more data elements in the property of the control 
  151.     associated with the dialog box item with index number 
  152.     index, by sending a WN_SET message to the control.
  153.  
  154.     The parameter par is assumed to be a pointer to a struct that 
  155.     specifies the data to be set. The type of struct that is 
  156.     expected depends on the class of the control that is being 
  157.     set; the various structs are described in the following 
  158.     Dialog Controls chapter.
  159.  
  160.     Setting
  161.     
  162.     A choice list is set by passing a pointer to an SE_CHLIST struct 
  163.     to the wn_set method
  164.  
  165.     typedef struct
  166.        {
  167.         UWORD set_flags;    /* which fields are significant */
  168.         PR_VAROOT *data;    /* pointer to array containing data */
  169.         UWORD nsel;         /* index of current item */
  170.         } SE_CHLIST;
  171.  
  172.     The property to be set is indicated by ORing one or more of 
  173.     the following flags into the flags field of the above struct.
  174.     
  175.     SE_CHLIST_NSEL    the index of the current item is to be set.
  176.  
  177.     SE_CHLIST_DATA    the data is to be replaced. The replacement
  178.             data is a string array - see variable arrays
  179.             in the OLIB Reference manual.
  180.  
  181.     SE_CHLIST_RETAIN    data should not be destroyed on
  182.                 destruction of the choice list
  183.                 control - once set this flag cannot
  184.                 be cleared.
  185.  
  186.     The content of a choice list can be set dynamically, say, 
  187.     from the dialog's dl_dyn_init method. However, changing the 
  188.     content of a choice list once the dialog has become visible 
  189.     is not recommended, since the width of the dialog box is set 
  190.     on initialisation. If the choice list content must be replaced, 
  191.     then care should be taken to ensure that the text does not 
  192.     become too wide for the dialog box to display.
  193.  
  194. *    Run the dialog. This is done using the standard DIALOG 
  195.     function.
  196.  
  197. While viewing the OPL code, bear the following in mind:
  198.  
  199. *    DatDialogPtr is a magic static always at location 0x36. 
  200.     System user interface library code may assume that this 
  201.     location contains a pointer to the current dialog structure. 
  202.     Otherwise it is free for use by application code. Hence, this 
  203.     value will almost certainly be NULL until dINIT is 
  204.     complete.
  205.  
  206. *    Note the use of ENTERSEND0() to ensure error values are 
  207.     returned appropriately (given that many of the functions 
  208.     call p_leave() rather than return an error). Using the 
  209.     SEND function may result in your application panicing 
  210.     unexcpectedly if an error arises.
  211.  
  212. *    Note the extensive use of '#' as a prefix to variable names. 
  213.     This is done to tell OPL that the following expression is the 
  214.     address to be used - not a variable whose address is to be 
  215.     taken.
  216.  
  217. *    Note the use of UADD to skip the leading count byte of an 
  218.     OPL string. This ensures that we do not cause any 'Integer 
  219.     overflow' errors.
  220.