www.pudn.com > SmartFDISK.zip > tinplong.cpp


#define TV1 
/*----------------------------------------------------------------------- 
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. 
 
TInputLong will be of most interest to users of Turbo Vision 1.x.  If you're 
using TVision version 2.0,  you may prefer using a TInputLine with a 
TRangeValidator. 
 
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 
#define Uses_Message 
 
#if defined (TV2) 
#   include  
#   include  
#elif defined (TV1) 
#   include  
#   include   
#else 
#   error TV1 or TV2 must be defined 
#endif 
 
#include "Msg.h" 
 
#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; 
} 
 
 
uint32 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, getMessage(0x100), 
		s, lLim, formHexStr(sl, lLim), uLim, formHexStr(su, uLim)); 
   else 
	 messageBox(mfError | mfOKButton, getMessage(0x101), 
		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";