home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BUG 4
/
BUGCD1997_05.BIN
/
aplic
/
clip4win
/
clip4win.exe
/
C4W30E.HUF
/
SOURCE
/
WREADER.PRG
< prev
Wrap
Text File
|
1993-06-07
|
9KB
|
234 lines
/*
Function: WGetReader( <oGet>, <hWnd>, <aGets>, <aButtons>, <nBHeight> )
Purpose: Process one GET
Heavily modified for use with Clip-4-Win
Parameters: <oGet> - currently active GET object
<hWnd> - handle to current active window
<aGets> - current GETLIST array (required for re-drawing -
see DrawGets() below)
<aButtons> - array containing pushbutton window handles
necessary for resizing in the event of redraw
<nBHeight> - button height (ibid)
Authors: Greg Lief and John Skelton
Explanation:
The main reasons for the existence of this reader are:
1. To allow the prompt to be kept with the GET object
(this is encapsulation, of course), e.g. to be
able to re-draw the prompts and GETs in a window
2. To provide mouse control (possible with Clip-4-Win's
ReadModeless() GET system as standard)
3. To support push buttons
of course, item 1 should be a new class (GetWithPrompt),
as should item 3. Item 2 would be inherited by the new
GetWithPrompt class. The painful use of cargo in this
reader becomes unnecessary.
*/
#include "getexit.ch"
#include "inkey.ch"
#include "windows.ch"
//───── structure for Get object's cargo array
#define GET_LENGTH 1 // required for mouse jumps to other GETs
#define GET_PROMPT 2 // @..SAY associated with this GET
#define PROMPT_ROW 3 // row at which to display GET_PROMPT
#define PROMPT_COL 4 // column at which to display GET_PROMPT
#define PROMPT_COLOR 5 // color in which to display GET_PROMPT
#define FORCE_FOCUS 6 // forces setFocus() (see notes below)
#define LASTGET 7 // flag indicating last GET
//───── manifest constants for GetClientRect() and GetDIBRect() arrays
//───── note that since Top and Left are always 0, they are unused
#define W_RIGHT 3
#define W_BOTTOM 4
procedure WGetReader( oGet, nEvent, hWnd, getlist, aButtons, buttonheight )
local nNewget
local nButtons
local aRect
local x
local nWidth
static lFirsttime := .t.
// read the GET if the WHEN condition is satisfied
if oGet:exitState == GE_NOEXIT .or. ( GetPreValidate(oGet) )
/*
activate the GET for reading (but not for the very first GET because
we must first send it through the resizing grinder, a/k/a DrawGets()).
However, note that if we have used the pushbuttons to move the record
pointer, the GETs will already have been redisplayed (in the interest
of performance). Therefore, we will "force" focus to be set by setting
a flag in the cargo for this GET.
*/
if ! lFirsttime .or. oGet:cargo[FORCE_FOCUS]
if !oGet:hasFocus
oGet:SetFocus()
endif
oGet:cargo[FORCE_FOCUS] := lFirsttime := .f.
else
/*
If we are here for the first time, toggle the "lastget" flag on the
last GET in the Getlist array. This is necessary for resetting the
lFirsttime flag below in the event that we press Enter to exit the
READ. This could probably be done in the calling program, but I
wanted it to be transparent which is why it is here.
*/
ATail(getlist):cargo[LASTGET] := .t.
endif
while ( oGet:exitState == GE_NOEXIT )
// check for initial typeout (no editable positions)
if ( oGet:typeOut )
oGet:exitState := GE_ENTER
end
// apply keystrokes until exit
while ( oGet:exitState == GE_NOEXIT )
do case
case nEvent == EVENT_KEY
GetApplyKey(oGet, Inkey(0) )
case nEvent == EVENT_LCLICK
// check the mouse position
if PosInGetList(GetList, MouseRow(), MouseCol()) == nil
// not a click in any of the GetList
return // wait for the next event
endif
// getting here means it's a click on a GET
// (the current one if MouseRow() == oGet:row)
if MouseRow() == oGet:row
// current GET, so change the position
oGet:pos -= col() - MouseCol()
oGet:Display()
elseif MouseRow() < oGet:row
oGet:exitState := GE_UP
else
oGet:exitState := GE_DOWN
endif
case nEvent == EVENT_CONTROL // i.e., a button was pushed
oGet:exitState := GE_WRITE
otherwise
do case
//───── force redrawing GETs unless window was minimized
case nEvent == EVENT_REDRAW .and. ! IsIconic(hWnd)
HideCaret(hWnd)
DrawGets(getlist)
ShowCaret(hWnd)
//───── must now activate first GET if we're on it
if lFirsttime
lFirsttime := .f.
oGet:setFocus()
endif
aeval(aButtons, {|hBtn| InvalidateRect(hBtn)})
case nEvent == EVENT_WINSIZE
//───── if we are using pushbuttons at the base of the
//───── data entry screen, resize them accordingly
if aButtons <> NIL
nButtons := len(aButtons)
aRect := GetClientRect(hWnd)
nWidth := aRect[W_RIGHT] / nButtons
for x := 1 to nButtons
MoveWindow(aButtons[x], nWidth * (x - 1), ;
arect[W_BOTTOM] - buttonheight, ;
nWidth, buttonheight, .f.)
next
endif
InvalidateRect(hWnd)
case nEvent == EVENT_CLOSE .or. ;
nEvent == EVENT_DESTROY
// oGet:exitState := GE_ESCAPE // not needed
endcase
endcase
if oGet:exitState == GE_NOEXIT
return // wait for another event
endif
enddo
// disallow exit if the VALID condition is not satisfied
if ( !GetPostValidate(oGet) )
oGet:exitState := GE_NOEXIT
return // wait for another event
endif
enddo
// de-activate the GET
oGet:KillFocus()
//───── if we just finished the READ, reset static flag
if oGet:exitState == GE_ESCAPE .or. oGet:exitState == GE_WRITE .or. ;
( oGet:exitState == GE_ENTER .and. oGet:cargo[LASTGET] )
lFirsttime := .t.
endif
endif
return
/*
DrawGets(<aGetlist>)
Redraw GETs and accompanying static text, tweaking ::picture if
necessary to make GET fit within window
*/
static function DrawGets(getlist)
local nGets := len(getlist)
local x
local oGet
local nLen
local nWidth
local y
local lActive := .f.
local oldcolor
local r := row()
local c := col()
for x := 1 to nGets
oGet := getlist[x]
setpos(oGet:cargo[PROMPT_ROW], oGet:cargo[PROMPT_COL])
dispout(oGet:cargo[GET_PROMPT], oGet:cargo[PROMPT_COLOR])
//───── initialize GET coordinates if none were specified
//───── (note that Clipper initializes them to 0, not NIL
if oGet:row == 0
oGet:row := row()
endif
if oGet:col == 0
oGet:col := col() + 1
endif
nLen := len(transform(oGet:varGet(), ;
iif(oGet:picture == nil, "", oGet:picture)))
nWidth := maxcol() - oGet:col + 1
//───── remove previous @S clause from picture (if applicable)
//───── this is necessary if the GETs had to be truncated
//───── but you have just resize the window to make it larger
if ( y := at("@S", oGet:picture) ) > 0
oGet:picture := substr(oGet:picture, 1, y - 1)
endif
//───── if GET won't fit within this window, use @S picture to scroll it
if nLen > nWidth
oGet:picture := if(oGet:picture == NIL, '', oGet:picture) + ;
"@S" + ltrim(str(nWidth))
oGet:cargo[GET_LENGTH] := nWidth
else
oGet:cargo[GET_LENGTH] := nLen
endif
oGet:display()
if oGet:hasFocus
// sensible place for the caret (= Clipper cursor)
r = row()
c = col()
endif
next
setpos(r, c)
return nil
//───── end of file WREADER.PRG