home *** CD-ROM | disk | FTP | other *** search
/ BUG 4 / BUGCD1997_05.BIN / aplic / clip4win / clip4win.exe / C4W30E.HUF / SOURCE / WREADER.PRG < prev   
Text File  |  1993-06-07  |  9KB  |  234 lines

  1. /*
  2.     Function:   WGetReader( <oGet>, <hWnd>, <aGets>, <aButtons>, <nBHeight> )
  3.     Purpose:    Process one GET
  4.                 Heavily modified for use with Clip-4-Win
  5.     Parameters: <oGet> - currently active GET object
  6.                 <hWnd> - handle to current active window
  7.                 <aGets> - current GETLIST array (required for re-drawing -
  8.                           see DrawGets() below)
  9.                 <aButtons> - array containing pushbutton window handles
  10.                              necessary for resizing in the event of redraw
  11.                 <nBHeight> - button height (ibid)
  12.     Authors:    Greg Lief and John Skelton
  13.     Explanation:
  14.                 The main reasons for the existence of this reader are:
  15.                     1.  To allow the prompt to be kept with the GET object
  16.                         (this is encapsulation, of course), e.g. to be
  17.                         able to re-draw the prompts and GETs in a window
  18.                     2.  To provide mouse control (possible with Clip-4-Win's
  19.                         ReadModeless() GET system as standard)
  20.                     3.  To support push buttons
  21.                 of course, item 1 should be a new class (GetWithPrompt),
  22.                 as should item 3.  Item 2 would be inherited by the new
  23.                 GetWithPrompt class.  The painful use of cargo in this
  24.                 reader becomes unnecessary.
  25. */
  26.  
  27. #include "getexit.ch"
  28. #include "inkey.ch"
  29. #include "windows.ch"
  30.  
  31. //───── structure for Get object's cargo array
  32. #define GET_LENGTH    1   // required for mouse jumps to other GETs
  33. #define GET_PROMPT    2   // @..SAY associated with this GET
  34. #define PROMPT_ROW    3   // row at which to display GET_PROMPT
  35. #define PROMPT_COL    4   // column at which to display GET_PROMPT
  36. #define PROMPT_COLOR  5   // color in which to display GET_PROMPT
  37. #define FORCE_FOCUS   6   // forces setFocus() (see notes below)
  38. #define LASTGET       7   // flag indicating last GET
  39.  
  40.  
  41. //───── manifest constants for GetClientRect() and GetDIBRect() arrays
  42. //───── note that since Top and Left are always 0, they are unused
  43. #define W_RIGHT  3
  44. #define W_BOTTOM 4
  45.  
  46. procedure WGetReader( oGet, nEvent, hWnd, getlist, aButtons, buttonheight )
  47. local nNewget
  48. local nButtons
  49. local aRect
  50. local x
  51. local nWidth
  52. static lFirsttime := .t.
  53.  
  54. // read the GET if the WHEN condition is satisfied
  55. if oGet:exitState == GE_NOEXIT .or. ( GetPreValidate(oGet) )
  56.  
  57.    /*
  58.      activate the GET for reading (but not for the very first GET because
  59.      we must first send it through the resizing grinder, a/k/a DrawGets()).
  60.      However, note that if we have used the pushbuttons to move the record
  61.      pointer, the GETs will already have been redisplayed (in the interest
  62.      of performance).  Therefore, we will "force" focus to be set by setting
  63.      a flag in the cargo for this GET.
  64.    */
  65.    if ! lFirsttime .or. oGet:cargo[FORCE_FOCUS]
  66.       if !oGet:hasFocus
  67.          oGet:SetFocus()
  68.       endif
  69.       oGet:cargo[FORCE_FOCUS] := lFirsttime := .f.
  70.    else
  71.       /*
  72.         If we are here for the first time, toggle the "lastget" flag on the
  73.         last GET in the Getlist array.  This is necessary for resetting the
  74.         lFirsttime flag below in the event that we press Enter to exit the
  75.         READ.  This could probably be done in the calling program, but I
  76.         wanted it to be transparent which is why it is here.
  77.       */
  78.       ATail(getlist):cargo[LASTGET] := .t.
  79.    endif
  80.  
  81.    while ( oGet:exitState == GE_NOEXIT )
  82.  
  83.       // check for initial typeout (no editable positions)
  84.       if ( oGet:typeOut )
  85.          oGet:exitState := GE_ENTER
  86.       end
  87.  
  88.       // apply keystrokes until exit
  89.       while ( oGet:exitState == GE_NOEXIT )
  90.          do case
  91.             case nEvent == EVENT_KEY
  92.                GetApplyKey(oGet, Inkey(0) )
  93.             case nEvent == EVENT_LCLICK
  94.                // check the mouse position
  95.                if PosInGetList(GetList, MouseRow(), MouseCol()) == nil
  96.                   // not a click in any of the GetList
  97.                   return    // wait for the next event
  98.                endif
  99.  
  100.                // getting here means it's a click on a GET
  101.                // (the current one if MouseRow() == oGet:row)
  102.                if MouseRow() == oGet:row
  103.                   // current GET, so change the position
  104.                   oGet:pos -= col() - MouseCol()
  105.                   oGet:Display()
  106.                elseif MouseRow() < oGet:row
  107.                   oGet:exitState := GE_UP
  108.                else
  109.                   oGet:exitState := GE_DOWN
  110.                endif
  111.             case nEvent == EVENT_CONTROL    // i.e., a button was pushed
  112.                oGet:exitState := GE_WRITE
  113.             otherwise
  114.                do case
  115.                   //───── force redrawing GETs unless window was minimized
  116.                   case nEvent == EVENT_REDRAW .and. ! IsIconic(hWnd)
  117.                      HideCaret(hWnd)
  118.                      DrawGets(getlist)
  119.                      ShowCaret(hWnd)
  120.                      //───── must now activate first GET if we're on it
  121.                      if lFirsttime
  122.                         lFirsttime := .f.
  123.                         oGet:setFocus()
  124.                      endif
  125.                      aeval(aButtons, {|hBtn| InvalidateRect(hBtn)})
  126.                   case nEvent == EVENT_WINSIZE
  127.                      //───── if we are using pushbuttons at the base of the
  128.                      //───── data entry screen, resize them accordingly
  129.                      if aButtons <> NIL
  130.                         nButtons := len(aButtons)
  131.                         aRect := GetClientRect(hWnd)
  132.                         nWidth := aRect[W_RIGHT] / nButtons
  133.                         for x := 1 to nButtons
  134.                            MoveWindow(aButtons[x], nWidth * (x - 1), ;
  135.                                       arect[W_BOTTOM] - buttonheight, ;
  136.                                       nWidth, buttonheight, .f.)
  137.                         next
  138.                      endif
  139.                      InvalidateRect(hWnd)
  140.                   case nEvent == EVENT_CLOSE .or. ;
  141.                        nEvent == EVENT_DESTROY
  142. //                     oGet:exitState := GE_ESCAPE    // not needed
  143.                endcase
  144.          endcase
  145.  
  146.          if oGet:exitState == GE_NOEXIT
  147.             return    // wait for another event
  148.          endif
  149.  
  150.       enddo
  151.  
  152.       // disallow exit if the VALID condition is not satisfied
  153.       if ( !GetPostValidate(oGet) )
  154.          oGet:exitState := GE_NOEXIT
  155.          return        // wait for another event
  156.       endif
  157.  
  158.    enddo
  159.  
  160.    // de-activate the GET
  161.    oGet:KillFocus()
  162.  
  163.    //───── if we just finished the READ, reset static flag
  164.    if oGet:exitState == GE_ESCAPE .or. oGet:exitState == GE_WRITE .or. ;
  165.                  ( oGet:exitState == GE_ENTER .and. oGet:cargo[LASTGET] )
  166.       lFirsttime := .t.
  167.    endif
  168.  
  169. endif
  170. return
  171.  
  172.  
  173. /*
  174.     DrawGets(<aGetlist>)
  175.     Redraw GETs and accompanying static text, tweaking ::picture if
  176.     necessary to make GET fit within window
  177. */
  178. static function DrawGets(getlist)
  179. local nGets := len(getlist)
  180. local x
  181. local oGet
  182. local nLen
  183. local nWidth
  184. local y
  185. local lActive := .f.
  186. local oldcolor
  187. local r := row()
  188. local c := col()
  189. for x := 1 to nGets
  190.    oGet := getlist[x]
  191.    setpos(oGet:cargo[PROMPT_ROW], oGet:cargo[PROMPT_COL])
  192.    dispout(oGet:cargo[GET_PROMPT], oGet:cargo[PROMPT_COLOR])
  193.  
  194.    //───── initialize GET coordinates if none were specified
  195.    //───── (note that Clipper initializes them to 0, not NIL
  196.    if oGet:row == 0
  197.       oGet:row := row()
  198.    endif
  199.    if oGet:col == 0
  200.       oGet:col := col() + 1
  201.    endif
  202.  
  203.    nLen := len(transform(oGet:varGet(),        ;
  204.              iif(oGet:picture == nil, "", oGet:picture)))
  205.    nWidth := maxcol() - oGet:col + 1
  206.  
  207.    //───── remove previous @S clause from picture (if applicable)
  208.    //───── this is necessary if the GETs had to be truncated
  209.    //───── but you have just resize the window to make it larger
  210.    if ( y := at("@S", oGet:picture) ) > 0
  211.       oGet:picture := substr(oGet:picture, 1, y - 1)
  212.    endif
  213.  
  214.    //───── if GET won't fit within this window, use @S picture to scroll it
  215.    if nLen > nWidth
  216.       oGet:picture := if(oGet:picture == NIL, '', oGet:picture) + ;
  217.                          "@S" + ltrim(str(nWidth))
  218.       oGet:cargo[GET_LENGTH] := nWidth
  219.    else
  220.       oGet:cargo[GET_LENGTH] := nLen
  221.    endif
  222.    oGet:display()
  223.    if oGet:hasFocus
  224.       // sensible place for the caret (= Clipper cursor)
  225.       r = row()
  226.       c = col()
  227.    endif
  228. next
  229. setpos(r, c)
  230. return nil
  231.  
  232.  
  233. //───── end of file WREADER.PRG
  234.