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";