************************************************** *-- Class: txtnumber (c:\cdbk90\common30\libs\ccustcurrency.vcx) *-- ParentClass: textbox *-- BaseClass: textbox *-- Time Stamp: 05/01/07 06:59:02 PM *-- Numeric text box class - adding machine style (nStyle = 1) or calculator stype (nStyle = 2) * #INCLUDE "c:\cdbk90\amline\include\appincl.h" * DEFINE CLASS txtnumber AS textbox Alignment = 1 Value = 0 Format = "RZ" Height = 23 InputMask = "9" ForeColor = RGB(0,0,0) csofar = "'0'" PROTECTED ndecimal ndecimal = 0 *-- 1 = adding machine style, 2 = calculator style PROTECTED nstyle nstyle = 2 PROTECTED cbefinputmask cbefinputmask = "99,999,999" PROTECTED ceurinputmask ceurinputmask = "99,999.99" *-- Peut on modifier le inputmask au lancement et à la frappe ? lallowchangeinputmask = .T. *-- Est ce un champs devise ? liscurrency = .T. PROTECTED coldinputmask coldinputmask = "" ctable = "" ccontrolsource = "" *-- Valeur de la clé primaire de la vue sur laquelle est basée le controlsource de ce textbox. nprimarykeyview = 0 *-- Nombre maximum de chiffres compris dans l'inputMask. nmaxinputmask = 8 Name = "txtnumber" *-- .T. after the decimal key has been pressed PROTECTED ldecimalpressed *-- Peut on redéfinir l'inputmask après chaque déplacement du pointeur de fichier ds la méthode refresh() ? lallowcalculateinputmask = .F. lgrid = .F. PROCEDURE setvalue LPARAMETERS nVal *--------------------------------------------- *-- Si mode calculette et pas de décimal. LOCAL nValue *---------------------------------------------- IF PCOUNT() = 1 nValue = nVal ELSE nValue = VAL( ALLTR( THIS.cSoFar ) ) ENDIF THIS.VALUE = nValue THIS.lputinputmask( nValue ) *THIS.REFRESH() * Milcent <b. *THIS.SELSTART = LEN( ALLTR( THIS.INPUTMASK ) ) &&+ 1 ENDPROC PROTECTED PROCEDURE setdecimal LOCAL lnDec, ; lnDecPos,; cSoFar WITH THIS cSoFar = ALLTR( .cSoFar ) *-- Si ',00' c'est qu'on vient de taper la touche . ou , IF AT( ",00" , cSoFar ) > 0 .lDecimalPressed = .T. *-- 22/01/2002 IF .nDecimal = 0 .nDecimal = 1 ENDIF RETURN .T. ENDIF lnDecPos = RAT( ",", cSoFar ) IF lnDecPos > 0 lnDec = LEN( cSoFar ) - lnDecPos .lDecimalPressed = .T. *-- Si le 2eme chiffre après la virgule <> "0" alors on est à la 2eme décimale. DO CASE CASE RIGHT( cSoFar , 1 ) <> "0" .nDecimal = 3 && La prochaine est impossible ! CASE RIGHT( cSoFar , 1 ) = "0" .nDecimal = 2 OTHER .nDecimal = 1 ENDCASE ELSE lnDec = 0 .lDecimalPressed = .F. .nDecimal = 0 ENDIF *THIS.nDecimal = MAX( 1, 10 ^ lnDec) ENDWITH ENDPROC PROCEDURE lputinputmask LPARAMETERS nValue *-- Cette procédure sert à définir : *-- A) l'INPUTMASK du textbox. *-- B) THIS.cSoFar. LOCAL cInputmask,; nMod,; cSoFar,; csign IF SIGN( nValue ) = -1 csign = "9" ELSE csign = "" ENDIF *----------------------------------------------------------------- *-- Déterminer le masque des entiers.02/06/2002. IF THIS.lAllowChangeInputMask *-- A) l'INPUTMASK du textbox. DO CASE CASE BETW( ABS ( nValue ) , 0 , 9.99 ) cInputmask = "9" CASE BETW( ABS ( nValue ) , 10 , 99.99 ) cInputmask = "99" CASE BETW( ABS ( nValue ) , 100 , 999.99 ) cInputmask = "999" CASE BETW( ABS ( nValue ) , 1000 , 9999.99 ) cInputmask = "9,999" CASE BETW( ABS ( nValue ) , 10000 , 99999.99 ) cInputmask = "99,999" CASE BETW( ABS ( nValue ) , 100000 , 999999.99 ) cInputmask = "999,999" CASE BETW( ABS ( nValue ) , 1000000 , 9999999.99 ) cInputmask = "9,999,999" CASE BETW( ABS ( nValue ) , 10000000 , 99999999.99 ) cInputmask = "99,999,999" ENDCASE nMod = MOD( nValue , 1 ) cSoFar = ConvertToChar( nValue ) *-------------------------------------------------------------- *-- C'est un nombre décimal si : *-- A) Si il y a un reste ds la division 129.47 / 1 donne 47 ( Refresh () ) *-- B) Si on vient de frapper le . DO CASE *-- Si la keypress . ou , et pas de restant de division. *-- Refresh() ne rentre pas ici puisque THIS.lDecimalPressed = .F. CASE THIS.lDecimalPressed = .T. AND nMod = 0 && Keypress AT( ',' , THIS.cSoFar ) > 0 cInputmask = cInputmask + ".99" *-- Ici on aura 15.00 car on a mis 2 qui *-- permet d'avoir deux décimales. THIS.cSoFar = ConvertToChar( nValue , 2 ) CASE nMod > 0.00 cInputmask = cInputmask + ".99" THIS.cSoFar = ConvertToChar( nValue , 2 ) &&cSoFar && ConvertToChar( nValue ) OTHERW *-- Ici on aura jammais 15.00 ! THIS.cSoFar = cSoFar && ConvertToChar( nValue ) ENDCASE THIS.INPUTMASK = csign + cInputmask THIS.SetDecimal() IF VERSION(2) = 2 WAIT WIND "csofar " + ALLTR( THIS.cSoFar ) + CR + ; "Inputmask " + THIS.INPUTMASK + CR +; "VALUE " + ALLT( STR( nValue , 7, 2) ) + CR +; "Restant de la division : " + ALLTR( STR( nMod, 9 , 3 ) ) + CR +; "Décimale " + ALLTR( STR( THIS.nDecimal ) ) NOWAI ENDIF ENDIF ENDPROC PROCEDURE Error *============================================================================== * Method: Error * Status: Public * Purpose: Handles errors * Author: Doug Hennig * Copyright: (c) 1996 Stonefield Systems Group Inc. * Last revision: 09/24/99 * Parameters: tnError - the error number * tcMethod - the method that caused the error * tnLine - the line number of the command in error * Returns: may return an error resolution string (see SFERRORS.H for * a list) or may RETURN, RETRY, or CANCEL * Environment in: if a global error handler object exists, it's in the global * variable oMasterError * a global ON ERROR routine may be in effect * Environment out: depends on the error resolution chosen *============================================================================== LPARAMETERS tnError, ; tcMethod, ; tnLine *!* Goapp.ctrlerror(tnError, ; *!* tcMethod, ; *!* tnLine,; *!* THIS) IF TYPE( "GoApp" )="O" Goapp.ctrlerror(tnError, ; tcMethod, ; tnLine,; THIS) ENDIF ENDPROC PROCEDURE GotFocus DODEFAULT() THIS.BACKCOLOR = RGB( 255,128, 0 ) SYS(2002) *SET CURSOR OFF *-- 06/06/2002.Pour les grids contenant des txtnumbers. IF THIS.lGrid THIS.lputinputmask( THIS.VALUE ) ENDIF ENDPROC PROCEDURE KeyPress LPARAMETERS nKeyCode, nShiftAltCtrl LOCAL lnDecPos DO CASE CASE THIS.READONLY * If the control is read-only... IF INLIST( nKeyCode, 13, 9, 15, 4, 19, 5, 24, 18, 3) * ...then the ENTER, TAB, BACKTAB, RIGHT ARROW, LEFT ARROW, * UP ARROW, DOWN ARROW, PGUP, and PGDN keys have default behavior, ELSE * ...all other keys have no effect. NODEFAULT ENDIF CASE nKeyCode >= 48 AND nKeyCode <= 57 * Digits 0 to 9 NODEFAULT *----------------------------------------------------------------- *-- Pour éviter d'avoir "01". IF ALLTR( THIS.cSoFar ) == "0" THIS.cSoFar = CHR( nKeyCode) ELSE *-- Si le Nombre de caractère IF LEN( THIS.INPUTMASK ) > THIS.nMaxInputMask =Errormsg( "La saisie de chiffres est limitée à " + ; ALLTR( STR( THIS.nMaxInputMask ) ) + " !" ) RETURN .F. ENDIF *-------------------------------------------------------------- *-- Si c'est un nombre décimal. lnDecPos = RAT( "," , THIS.cSoFar ) IF THIS.lDecimalPressed = .T. AND lnDecPos > 0 *----------------------------------------------------------- *-- Si la 2eme décimale = "0" et la première décimale <> "0" *-- ce sera d'office la deuxième décimale. *-- On découpe THIS.cSoFar pour recevoir ensuite *-- la valeur chiffrée au bon endroit. DO CASE CASE THIS.nDecimal = 1 IF nKeyCode = 48 && 0 THIS.nDecimal = 2 ELSE THIS.cSoFar = STUFF( THIS.cSoFar , lnDecPos + 1 , 1 , CHR( nKeyCode ) ) ENDIF CASE THIS.nDecimal = 2 THIS.cSoFar = STUFF( THIS.cSoFar , lnDecPos + 2 , 1 , CHR( nKeyCode ) ) CASE THIS.nDecimal = 3 *-- Si les 2 décimales ont déjà été tapées. WAIT WIND " On ne peut avoir que deux décimales..." NOWAIT ?? CHR(7) RETURN .F. OTHER =Errormsg(" Cas Non Prévus ") ENDCASE ELSE *-- Si pas nombre décimal. THIS.cSoFar = ALLTR( THIS.cSoFar ) + CHR( nKeyCode) ENDIF ENDIF THIS.SetValue() THIS.INTERACTIVECHANGE() && Defeated by NODEFAULT so call it explicitly. CASE nKeyCode = 43 * + key NODEFAULT IF LEFT( THIS.cSoFar,1) = "-" THIS.cSoFar = SUBSTR( THIS.cSoFar,2) THIS.SetValue() ENDIF THIS.INTERACTIVECHANGE() && Defeated by NODEFAULT so call it explicitly. CASE nKeyCode = 45 * - key NODEFAULT IF LEFT( THIS.cSoFar,1) <> "-" THIS.cSoFar = "-" + THIS.cSoFar THIS.SetValue() ENDIF THIS.INTERACTIVECHANGE() && Defeated by NODEFAULT so call it explicitly. CASE nKeyCode = 46 OR nKeyCode = 44 * [.] Key OR [,] Key NODEFAULT *---------------------------------------------------- *-- Si on a pas encore appuyé sur le point (.) *-- On passe en mode décimal SI !!!! 21/11/2001 : *-- A) on est pas un textbox currency ( *-- B) On est un currency et c'est l'euro ! *---------------------------------------------------- IF THIS.lDecimalPressed = .T. WAIT WIND "Touche décimale déjà pressée " NOWAIT ?? CHR( 7 ) NODEFAU RETURN .F. ENDIF *---------------------------------------------------- IF THIS.liscurrency = .T. IF Goapp.ccurrentcurrency = "EUR" THIS.lDecimalPressed = .T. && LAISSER !!! THIS.cSoFar = THIS.cSoFar + ',' && CHR( nKeyCode) ELSE NODEFAU RETURN .F. ENDIF ELSE THIS.lDecimalPressed = .T. && LAISSER !!! THIS.cSoFar = THIS.cSoFar + ',' && CHR( nKeyCode) ENDIF * IF THIS.lDecimalPressed = .F. * THIS.lDecimalPressed = .T. && LAISSER !!! * THIS.cSoFar = THIS.cSoFar + ',' && CHR( nKeyCode) * ELSE * WAIT WIND "Touche décimale déjà pressée " NOWAIT * ?? CHR( 7 ) * NODEFAU * RETURN .F. *ENDIF THIS.lPutInputMask( THIS.VALUE ) THIS.INTERACTIVECHANGE() && Defeated by NODEFAULT so call it explicitly. CASE INLIST( nKeyCode, 13, 9, 15, 4, 19, 5, 24, 18, 3 , KEY_BACKSPACE ) * Enter, Tab, Backtab, Right Arrow, Left Arrow, Up Arrow, Down Arrow, * PgUp, and PgDn have default behavior. *-- 04/06/2001.----------------------------------------------------- IF nKeyCode = KEY_BACKSPACE && 127 *---------------------------------------------------------------- NODEFA lnDecPos = AT( ",00" , THIS.cSoFar ) *---------------------------------------------------------------- IF LEN( THIS.cSoFar ) > 0 *-- si c'est un nombre décimal où on a tapé 1 seul chiffre après la virgule *-- on a cependant un cSoFar = "13.50" *!* IF THIS.nDecimal = 1 AND THIS.lDecimalPressed = .T. *!* THIS.nDecimal = 0 *!* THIS.lDecimalPressed = .F. *!* ENDIF DO CASE *-- Si 45.00 => Doit donner 45 si ndecimal était à 1. (On retire la virgule) *-- Si 45.34 => Doit donner 45.30 si ndecimal était à 3. CASE INLIST( THIS.nDecimal , 0 , 3 ) THIS.cSoFar = LEFT( THIS.cSoFar , LEN( THIS.cSoFar ) - 1 ) *-- Si CASE THIS.nDecimal = 2 THIS.cSoFar = LEFT( THIS.cSoFar , LEN( THIS.cSoFar ) - 2 ) ENDCASE *-- 21/01/2002 IF THIS.lDecimalPressed = .T. AND THIS.nDecimal > 0 THIS.nDecimal = THIS.nDecimal - 1 IF THIS.nDecimal = 0 AND THIS.lDecimalPressed = .T. THIS.lDecimalPressed = .F. ENDIF ENDIF ENDIF THIS.SetValue() THIS.INTERACTIVECHANGE() && Defeated by NODEFAULT so call it explicitly. ENDIF *------------------------------------------------------------------- CASE nKeyCode = 7 * Del NODEFAULT THIS.cSoFar = "0" THIS.lDecimalPressed = .F. THIS.nDecimal = 0 THIS.SetValue() THIS.INTERACTIVECHANGE() && Defeated by NODEFAULT so call it explicitly. OTHERWISE * Ignore all other keys NODEFAULT ENDCASE *THIS.SELSTART = LEN( ALLTR( THIS.cSoFar ) ) *WAIT WIND ALLTR( STR( THIS.SELSTART ) ) + "/" + THIS.cSoFar NOWA *THIS.REFRESH() ENDPROC PROCEDURE Refresh LOCAL nPrimary,; nValue,; lcPrimaryKey,; lnSelect WITH THIS *-------------------------------------------------------------------------------------------------------- *-- Cette action change après le déplacement du pointeur de fichier ds la table. *-- Peut on redéfinir l'inputmask après chaque déplacement du pointeur de fichier ds la méthode refresh() ? *-- .F. Par défaut. *----------------------------------------------------------------------- *-- si THIS.cCONTROLSOURCE est défini. IF !EMPTY( .cCONTROLSOURCE ) lnSelect = SELECT( 0 ) SELECT ( .cTable ) *-- 06/2004 Placer les tables. IF CURSORGETPROP("SOURCETYPE") = DB_SRCTABLE nPrimary = EVAL( .cTable + '.iid' ) ELSE lcPrimaryKey = CURSORGETPROP("KEYFIELDLIST") *nPrimary = EVAL( .cTable + ".iid" ) nPrimary = EVAL( .cTable + '.' + lcPrimaryKey ) *lcParentView = EVAL(.oParentBizObj.cAlias + '.iTelephoneId' ) ENDIF SELECT( lnSelect ) ELSE IF .lGrid RETURN .T. ENDIF ENDIF IF nPrimary = .nPrimaryKeyView AND .nPrimaryKeyView # 0 *- Pas besoin d'aller plus loin RETURN .T. ELSE .nPrimaryKeyView = nPrimary .cSoFar = "" .lDecimalPressed = .F. .nDecimal = 0 ENDIF nValue = EVAL( .cTable + '.' + .cCONTROLSOURCE ) .Setvalue( nValue ) ENDWITH ENDPROC PROCEDURE LostFocus WITH THIS IF !EMPTY( .cCONTROLSOURCE ) *-- 12/2004 IF INLIST( UPPER( LEFT( THIS.cCONTROLSOURCE , 2 ) ) , "M." , "TH" ) STORE .VALUE TO ( THIS.cCONTROLSOURCE ) ELSE *-- Pour éviter un ischangead perpétuel. IF .VALUE <> EVAL( .cTable + '.' + .cCONTROLSOURCE ) REPL ( .cCONTROLSOURCE ) WITH .VALUE IN ( .cTable ) ENDIF ENDIF ENDIF .BACKCOLOR = RGB( 255,255,255 ) IF .lGrid .cSoFar ="" .nDecimal = 0 .lDecimalPressed = .F. ENDIF ENDWITH *SET CURSOR ON SYS(2002, 1) ENDPROC PROCEDURE Init IF THIS.PARENT.BASECLASS = "Column" THIS.lgrid = .T. ENDIF ENDPROC ENDDEFINE * *-- EndDefine: txtnumber **************************************************bernhart