Category : Miscellaneous Language Source Code
Archive   : DLGDS411.ZIP
Filename : TINPLONG.CPP

 
Output of file : TINPLONG.CPP contained in archive : DLGDS411.ZIP

/*-----------------------------------------------------------------------
TInputLong is a derivitave of TInputLine designed to accept long integer
numeric input. Since both the upper and lower limit of acceptable numeric
input can be set, TInputLong may be used for short integer or unsigned shorts
as well. Option flag bits allow optional hex input and display. A blank
field may optionally be rejected or interpreted as zero.

Data Members

ushort ilOptions;
the options (see constructor discussion).

long lLim, uLim;
the lower and upper limits.


Member functions

TInputLong( const TRect& bounds, int aMaxLen, long lowerLim,
long upperLim, ushort flags, const char* labelName = 0 ) :

Creats a TInputLong control. Flags may be a combination of:

ilHex = 1, //will enable hex input with leading '0x'
ilBlankEqZero = 2, //No input (blank) will be interpreted as '0'
ilDisplayHex = 4; //Number displayed as hex when possible

The optional labelName adds an identifier to any range error message.
Normally, this would be the same string as the field's label (minus
the '~'s).


virtual void TInputLong::write( opstream& os );
virtual void *TInputLong::read( ipstream& is );
static TStreamable *build();
TInputLong( StreamableInit streamableInit);

virtual ushort dataSize();
virtual void getData( void *rec );
virtual void setData( void *rec );

The transfer methods. dataSize is sizeof(long) and rec should be
the address of a long.


virtual Boolean rangeCheck();

Returns True if the entered string evaluates to a number >= lowerLim and
<= upperLim.


virtual void error();

error is called when rangeCheck fails. It displays a messagebox
indicating the allowable range. The optional labelName parameter in the
constructor is worked into the message to help identify the field.


virtual void handleEvent( TEvent& event );

handleEvent() filters out characters which are not appropriate to numeric
input. Tab and Shift Tab cause a call to rangeCheck() and a call to error()
if rangeCheck() returns false. The input must be valid to Tab from the
view. There's no attempt made to stop moving to another view with the mouse.


virtual Boolean valid( ushort command );

if TInputLine.valid() is true and Cmd is neither cmValid or cmCancel, valid
then calls rangeCheck(). If rangeCheck() is false, then error() is called
and valid() returns False.

------------------------------------------------------------------------*/

//#define Uses_TKeys
#define Uses_TInputLong
#define Uses_TInputLine
#define Uses_TDrawBuffer
#define Uses_TEvent
#define Uses_opstream
#define Uses_ipstream
#define Uses_MsgBox
#include
#include
#include
#include "tinplong.h"

#if !defined( __CTYPE_H )
#include
#endif // __CTYPE_H

#if !defined( __STRING_H )
#include
#endif // __STRING_H

#if !defined( __DOS_H )
#include
#endif // __DOS_H

char * formHexStr(char *s, long L)
{
if (L < 0)
{
s[0] = '-'; s[1] = '0'; s[2] = 'x';
ltoa(-L, &s[3], 16);
}
else
{s[0] = '0'; s[1] = 'x';
ltoa(L, &s[2], 16);
}
return s;
}

TInputLong::TInputLong( const TRect& bounds, int aMaxLen, long lowerLim,
long upperLim, ushort flags, const char* labelName ) :
TInputLine(bounds, aMaxLen),
lLim (lowerLim),
uLim(upperLim),
ilOptions(flags),
label(newStr(labelName))

{
if (ilOptions & ilDisplayHex)
ilOptions |= ilHex;
if (ilOptions & ilBlankEqZero)
strcpy(data, "0");
}

TInputLong::~TInputLong()
{
if (label) delete label;
}


ushort TInputLong::dataSize()
{
return sizeof(long);
}

void TInputLong::getData( void *rec )
{
long L;
if (data[0] == '\0' && (ilOptions & ilBlankEqZero))
strcpy(data, "0");
if ( (ilHex & ilOptions) && (strchr(data, 'X') || strchr(data, 'x')) )
L = strtol(data, 0, 16);
else L = strtol(data, 0, 10);
*(long*)rec = L;
}

void TInputLong::handleEvent( TEvent& event )
{
if (event.what == evKeyDown)
{switch (event.keyDown.keyCode)
{
case kbTab:
case kbShiftTab:
if (!rangeCheck())
{error();
selectAll(True);
clearEvent(event);
}
break;
}
}
if (event.keyDown.charScan.charCode)
{
int ch = toupper(event.keyDown.charScan.charCode);
switch (ch)
{
case '-' : if ( !(lLim < 0 && (curPos == 0 || selEnd > 0)) )
clearEvent(event); break;
case 'X' : if ( (ilOptions & ilHex) &&
(curPos == 1 && data[0] == '0')
|| (curPos == 2 && data[0] == '-' && data[1] == '0') );
else clearEvent(event);
break;
case 'A' :
case 'B' :
case 'C' :
case 'D' :
case 'E' :
case 'F' : if (!strchr(data, 'X') && !strchr(data, 'x') )
clearEvent(event);
break;
default : if ((ch < '0' || ch > '9') && (ch < 1 || ch > 0x1B))
clearEvent(event);
break;
}
}
TInputLine::handleEvent(event);
}

void TInputLong::setData( void *rec )
{
char s[40];
long L = *(long*)rec;
if (L > uLim) L = uLim;
else if (L < lLim) L = lLim;
if (ilOptions & ilDisplayHex)
formHexStr(s, L);
else ltoa(L, s, 10);
memcpy( data, s, maxLen );
data[maxLen] = EOS;
selectAll( True );
}

Boolean TInputLong::rangeCheck()
{
long L;
char *endptr;
if (data[0] == '\0')
if (ilOptions & ilBlankEqZero)
strcpy(data, "0");
else return False;
if ( (ilHex & ilOptions) && (strchr(data, 'X') || strchr(data, 'x')) )
L = strtol(data, &endptr, 16);
else L = strtol(data, &endptr, 10);
return Boolean( (L >= lLim) && (L <= uLim) && (*endptr == 0) );
}

void TInputLong::error()
#define SIZE 60
{ char sl[40], su[40], s[SIZE];
if (label == 0) s[0] = '\0';
else {
strcpy(s, "\"");
strncat(s, label, SIZE-4);
strcat(s, "\"\n");
}
if (ilHex & ilOptions)
messageBox(mfError | mfOKButton, "%sValue not within range %ld(%s) to %ld(%s)",
s, lLim, formHexStr(sl, lLim), uLim, formHexStr(su, uLim));
else
messageBox(mfError | mfOKButton, "%sValue not within range %ld to %ld",
s, lLim, uLim);
}

Boolean TInputLong::valid(ushort command)
{
Boolean rslt = TInputLine::valid(command);
if (rslt && (command != 0) && (command != cmCancel))
{rslt = rangeCheck();
if (!rslt)
{error();
select();
selectAll(True);
}
}
return rslt;
}

void TInputLong::write( opstream& os )
{
TInputLine::write( os );
os << ilOptions << lLim << uLim;
os.writeString(label);
}

void *TInputLong::read( ipstream& is )
{
TInputLine::read( is );
is >> ilOptions >> lLim >> uLim;
label = is.readString();
return this;
}

TStreamable *TInputLong::build()
{
return new TInputLong( streamableInit );
}

TInputLong::TInputLong( StreamableInit ) : TInputLine( streamableInit )
{
}

const char * const near TInputLong::name = "TInputLong";