oForm = createobject("TestForm") oForm.visible = .t. read events define class TestForm as form add object edtValidated as ValidatedEditbox procedure QueryUnload clear events endproc enddefine define class ZipValidator as custom DigitCount = 5 function Init lparameters tnDigitCount if vartype( tnDigitCount ) = 'N' this.DigitCount = tnDigitCount endif endfunc function ValidateString lparameters tcString local array laString[1] local i, lnLineCount, lnValue if vartype( tcString ) = 'C' lnLineCount = alines( laString, tcString, .t. ) tcString = "" for i = 1 to lnLineCount if !empty( laString[i] ) laString[i] = transform( int( val( laString[i] ) ) ) * padr() is used because you are formatting ZIP Codes laString[i] = padr( laString[i], this.DigitCount, '0' ) tcString = tcString + laString[i] + chr(13) endif endfor endif return tcString endfunc enddefine define class ValidatedEditbox as editbox * default validator, for some reason createobject() won't work here Validator = null function Init lparameters toValidator * we are using deligation for the validator if vartype( toValidator ) = 'O' this.Validator = toValidator else this.Validator = createobject( "ZipValidator" ) endif endfunc procedure InteractiveChange * thanks to Mike Helland for his info on SelStart cursor positioning local lnSelStart lnSelStart = this.selstart this.value = this.Validator.ValidateString( this.value ) this.selstart = lnSelStart endproc enddefine