Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Numeric input textbox class
Message
From
24/01/2005 07:19:40
Dorin Vasilescu
ALL Trans Romania
Arad, Romania
 
 
To
24/01/2005 06:46:35
Metin Emre
Ozcom Bilgisayar Ltd.
Istanbul, Turkey
General information
Forum:
Visual FoxPro
Category:
Classes - VCX
Miscellaneous
Thread ID:
00978451
Message ID:
00979959
Views:
33
>Hi Dorin,
>I want to see it. I did one before you but my class has some problems. I did't see a perfect numeric inputbox yet maybe your one has some new things. BTW look at my class. It's in download section (23418) ...
>
>>Hi all
>>
>>I've designed a numeric input custom textbox class.
>>If anyone is interested, I'll post the code here or to Download section.

Here is the code, the class needs only 3 custom properties
**************************************************
*-- Class:        txtnum (c:\projects\utils\numeric_textbox\numeric_textbox.vcx)
*-- ParentClass:  textbox
*-- BaseClass:    textbox
*-- Time Stamp:   12/20/05 01:21:00 PM
*
DEFINE CLASS txtnum AS textbox


	Alignment = 1
	Height = 23
	SelectOnEntry = .T.
	Width = 156
	*-- handle numerical or decimal part of value ( 'N' or 'D' ) ?
	ctextpart = "N"
	*-- flag needed to reset value after GotFocus
	cflag = ""
	*-- store number of decimals entered
	ndecimalsstored = 0
	Name = "txtnum"


	PROCEDURE KeyPress
		LPARAMETERS nKeyCode, nShiftAltCtrl

		LOCAL cNumeric, cDecimal, cValue, cPoint, cSeparator, cCurrency, cCleanText
		LOCAL nTextLength, nDecimalValue, nPointPosition, nOldValue, nOldSetDecimals

		cPoint = SET("Point")
		cSeparator = SET("Separator")
		cCurrency = SET("Currency",2)+SET("Currency",3)

		cCleanText = TRIM(CHRTRAN(this.Text, cCurrency+'$' , SPACE( LEN(cCurrency)+1) )) &&&&strip some display formatting by InputMask,Format
		nTextLength = LEN( cCleanText )
		nPointPosition =  IIF( cPoint $ cCleanText  , ATC(cPoint , cCleanText ) , LEN(cCleanText)+1) 
		nOldValue = this.Value 
		nOldSetDecimals = SET("Decimals")

		IF nPointPosition < LEN( cCleanText )
			SET DECIMALS TO (nTextLength-nPointPosition)	&&needed later for correct VAL() return 
		ENDIF  


		*get numeric and decimal part, if after GotFocus, start both with 0 ( string '' )
		*when first allowed numeric key is pressed
		IF this.cFlag  = 'gotfocus' AND nKeyCode >= 48 AND nKeyCode <= 57 AND nShiftAltCtrl = 0
			cNumeric = ''
			cDecimal = ''
			this.cFlag = 'keypress'
		ELSE 
			cNumeric = ALLTRIM(IIF( nPointPosition < LEN(cCleanText) , LEFT(cCleanText , nPointPosition-1) , cCleanText ))
			cNumeric = CHRTRAN(cNumeric, cSeparator , '')
			IF VAL( SUBSTR(cCleanText , nPointPosition+1) ) = 0
				cDecimal = ''
			ELSE 
				cDecimal = ALLTRIM( STR( VAL( SUBSTR(cCleanText, nPointPosition+1) ) ))
			ENDIF 
		ENDIF 

		DO CASE 
			CASE this.ReadOnly 
			CASE nKeyCode >= 48 AND nKeyCode <= 57 AND nShiftAltCtrl = 0	&& 0 to 9
				NODEFAULT
				IF this.cTextPart = 'N' 	&&handle numerical part
					IF NOT '*' $TRANSFORM( VAL(cNumeric + CHR(nKeyCode)) ;
							, CHRTRAN(cCleanText ,' 0123456789'+cSeparator+cPoint,'99999999999'+',.')) &&check overflow

						cNumeric = cNumeric + CHR(nKeyCode)
					ELSE 
						*test set confirm , stay on textbox and beep if needed
						IF SET("Confirm") = 'ON'
							??CHR(7)
						ELSE
							KEYBOARD '{TAB}' 
						ENDIF 
					ENDIF 
				ELSE 				&&handle decimal part
					this.nDecimalsStored = this.nDecimalsStored + 1
					IF this.nDecimalsStored > LEN(cCleanText)- nPointPosition 
						IF SET("Confirm") = 'ON'
							??CHR(7)
						ELSE
							KEYBOARD '{TAB}' 
						ENDIF 
						this.nDecimalsStored = this.nDecimalsStored - 1
					ELSE 
						cDecimal = STUFF(cDecimal, this.nDecimalsStored,1, CHR(nKeyCode))
					ENDIF   
				ENDIF 
				cValue = cNumeric + cPoint + cDecimal
				this.Value = VAL(cValue)
			CASE nKeyCode = 43		&& +
				NODEFAULT
				this.Value = ABS(this.Value)
			CASE nKeyCode = 45		&& - 
				NODEFAULT
				this.Value = -this.Value 
			CASE CHR(nKeyCode) = SET("Point") AND cPoint $ cCleanText	&&point pressed
				NODEFAULT
				this.cTextPart = 'D'	&&will handle decimal part from now
			CASE INLIST( nKeyCode, 13, 9, 15, 5, 24, 18, 3)
				* Enter, Tab, Backtab, UArrow, DArrow, PgUp, PgDn - default beavior

			CASE nKeyCode = 7		&& Del, reset value to 0
				NODEFAULT
				cValue = '0'
				this.cTextPart = 'N' 
				this.nDecimalsStored = 0
				this.Value = VAL(cValue)
			CASE nKeyCode = 127		&& BackSpace, delete from decimal part or from numeric part
				NODEFAULT
				*if selected( SelectOnEntry = .T.) reset value to 0 
				IF this.SelLength = LEN(this.Text)
					cValue = '0' + cPoint + '0'
				ELSE 
					IF this.cTextpart ='N'
						IF LEN(cNumeric) >= 1
							cNumeric = LEFT(cNumeric , LEN(cNumeric) - 1)
						ELSE 
							cNumeric = ''
						ENDIF 
					ELSE 
						this.nDecimalsStored = this.nDecimalsStored - 1
						IF this.nDecimalsStored < 0		&& we need to step over the decimal point now
							this.nDecimalsStored = 0
							this.cTextPart = 'N' 
							IF LEN(cNumeric) >= 1
								cNumeric = LEFT(cNumeric , LEN(cNumeric) - 1)
							ELSE 
								cNumeric = ''
							ENDIF 
						ENDIF   
						cDecimal = STUFF(cDecimal, this.nDecimalsStored+1,1,'')
					ENDIF 
					cValue = cNumeric + cPoint + cDecimal
				ENDIF 

				this.Value = VAL(cValue)
			OTHERWISE
				* Ignore other keys, beep
				NODEFAULT
				??CHR(7)
		ENDCASE

		IF this.cTextpart = 'N'
			this.SelStart = nPointPosition 
		ELSE 
			this.SelStart = nPointPosition + this.nDecimalsStored + 1
		ENDIF    

		SET DECIMALS TO (nOldSetDecimals)

		IF this.Value <> nOldValue
			this.InteractiveChange() &&this needed to be executed programatic
		ENDIF
	ENDPROC


	PROCEDURE GotFocus
		IF SET("Point") $ this.Text 
			this.SelStart = ATC(SET("Point"),this.Text) 
		ELSE
			this.SelStart = LEN(this.Text)
		ENDIF
		this.cTextPart  = 'N'		&&handle numeric part after GotFocus()
		this.cflag  = 'gotfocus'
		this.nDecimalsStored = 0	&&so far typed decimals
		DODEFAULT()
	ENDPROC


ENDDEFINE
*
*-- EndDefine: txtnum
**************************************************
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform