Paged List Box Example

The following partial program shows a full implementation of a paged list box. Code that is incidental to the handling of the list box is omitted in the interest of brevity.
Tip: In the AcuGT > Sample directory of your installation, there is also a sample program called wheelevent.cbl. This program demonstrates how to create a paged list box, a paged grid, and wheelmouse events for scrolling the control.
file-control.
     select keywords-file
         assign to "techword.dat"
         organization is indexed
         access mode is dynamic
         record key is keyword-word
         file status is keyword-status.

file section.
fd  keywords-file.
01  keyword-record.
    03  keyword-key.
        05  keyword-word         pic x(15).
        05  keyword-id           pic 9(7).

working-storage section.

78  list-box-lines               value 16.

copy "acucobol.def".
copy "acugui.def".

77  keyword-status               pic xx.
77  number-reads-needed          pic 99.

* STATE-FLAG tracks where you are in the file.  
* READING-FORWARDS indicates that the last read was 
* of the last record shown in the box.  
* READING-BACKWARDS indicates that the last read 
* was of the first record in the box (via READ 
* PREVIOUS).  AT-START and AT-END handle special 
* cases when you reach either end of the file.

77  state-flag                   pic x.
    88  reading-forwards         value "f".
    88  reading-backwards        value "b".
    88  at-start                 value "s".
    88  at-end                   value "e".

77  list-data                    pic x(15).

77  key-status 
    is special-names crt status  pic 9(4).

* Note: although the program never directly 
* references the Screen Control data item, you have 
* to declare it anyway.  That is because "notify"
* style events will set it to the proper value when 
* entering an EXCEPTION PROCEDURE.  The value 
* generated causes the controlling ACCEPT statement 
* to continue processing after the exception 
* procedure finishes.  If you omit SCREEN-CONTROL, 
* then the result is that you exit the ACCEPT after 
* the exception procedure completes.  

01  screen-control
    is special-names screen control.
    03  accept-control            pic 9.
    03  control-value             pic 999.

01  event-status
    is special-names event status.
    03  event-type                pic x(4) comp-x.
    03  event-window-handle       handle.
    03  event-control-handle      handle.
    03  event-control-id          pic x(2) comp-x.
    03  event-data-1              signed-short.
    03  event-data-2              signed-long
    03  event-action              pic x comp-x.

screen section.
01  screen-1.
    03  list-1, list-box using list-data, 
        line 3, column 10, size 30,
        lines list-box-lines, 3-d,
        paged,
        exception procedure is list-1-handler.

* Other screen items typically found here

procedure division.
main-logic.
   open input keywords-file.
   set reading-forwards to true.

* Code to construct user's window omitted

   display screen-1.

* Load the first page of list box items

   modify list-1, mass-update = 1
   perform list-box-lines times 
      read keywords-file next record
         at end     set at-end to true
                    exit perform
         end-read
      modify list-1, 
             item-to-add = keyword-word
   end-perform
   modify list-1, mass-update = 0.

* Now activate the list box

   accept screen-1.

* Code to use the entered data omitted

   stop run.

* LIST-1-HANDLER handles all exceptions generated 
* by the list box.  The only exceptions you care 
* about are those that require a response in 
* order to manage the list box properly.

list-1-handler.
   if key-status = w-event
      evaluate event-type
        when ntf-pl-next
          perform get-next-item

        when ntf-pl-prev
          perform get-prev-item

        when ntf-pl-nextpage
          modify list-1, mass-update = 1
          perform get-next-item list-box-lines times
          modify list-1, mass-update = 0

        when ntf-pl-prevpage
          modify list-1, mass-update = 1
          perform get-prev-item list-box-lines times
          modify list-1, mass-update = 0

        when ntf-pl-first
          move low-values to keyword-word
          start keywords-file, 
                key not < keyword-word
             invalid key    exit paragraph
             end-start
          set reading-forwards to true
          modify list-1, mass-update = 1
          modify list-1, reset-list = 1
          perform get-next-item list-box-lines times
          modify list-1, mass-update = 0

        when ntf-pl-last
          move high-values to keyword-word
          start keywords-file,
                key not > keyword-word
             invalid key    exit paragraph
             end-start
          set reading-backwards to true
          modify list-1, mass-update = 1
          modify list-1, reset-list = 1
          perform get-prev-item list-box-lines times
          modify list-1, mass-update = 0

* In the search logic, if you get too close to the 
* end of the file, you simply act as if you wanted to 
* find the last full page.  Do this by setting the 
* event type to NTF-PL-LAST and re-evaluating.

        when ntf-pl-search
          inquire list-1,
                  search-text in keyword-word
          start keywords-file,
                key not < keyword-word
            invalid key 
                move ntf-pl-last to event-type
                go to list-1-handler
            end-start
          set reading-forwards to true
          modify list-1, mass-update = 1
          perform get-next-item list-box-lines times
          if at-end
            move ntf-pl-last to event-type
            go to list-1-handler
          end-if
          modify list-1, mass-update = 0
      end-evaluate
    end-if.

* GET-NEXT-ITEM handles all cases where you read 
* forwards through the file.  It adjusts for the 
* four possible states you could be in and then 
* retrieves the next record.  This record is added
* to the end of the list box.  In some cases, you 
* have to traverse over the page of records 
* currently displayed (because you are switching 
* direction).  

get-next-item.
   evaluate true
     when at-start
        move low-values to keyword-word
        start keywords-file, key not < keyword-word
          invalid key    exit paragraph
          end-start
        add 1 to list-box-lines 
            giving number-reads-needed
     when at-end
        exit paragraph
     when reading-backwards
        move list-box-lines to number-reads-needed
     when reading-forwards
        move 1 to number-reads-needed
     end-evaluate

     perform number-reads-needed times
        read keywords-file next record
          at end   set at-end to true
                   exit paragraph
          end-read
     end-perform

     modify list-1, 
       item-to-add = keyword-word

     set reading-forwards to true.

* GET-PREV-ITEM is the converse of GET-NEXT-ITEM.  
* It retrieves the previous record in the list and 
* adds it to the top of the list box.  The code is 
* structured identically to GET-NEXT-ITEM.  

get-prev-item.
   evaluate true
     when at-end
        move high-values to keyword-word
        start keywords-file, key not > keyword-word
            invalid key  exit paragraph
            end-start
        add 1 to list-box-lines 
            giving number-reads-needed
     when at-start
        exit paragraph
     when reading-forwards
        move list-box-lines to number-reads-needed
     when reading-backwards
        move 1 to number-reads-needed
   end-evaluate

perform number-reads-needed times
   read keywords-file previous record
     at end  set at-start to true
             exit paragraph
     end-read
end-perform

modify list-1
   insertion-index = 1
   item-to-add = keyword-word

set reading-backwards to true.