Recent

Author Topic: [SOLVED] TEdit accepting non-numeric values  (Read 5770 times)

odvesims

  • Full Member
  • ***
  • Posts: 176
[SOLVED] TEdit accepting non-numeric values
« on: August 10, 2017, 03:39:28 pm »
Hey There!

I have several TEdit controls with the property "NumberOnly" set to true. This works just fine on Windows. However, when I execute my program in linux (raspberry pi with raspbian), the same TEdit are accepting non-numeric values.  Any idea why it's causing this?
« Last Edit: August 14, 2017, 02:21:09 pm by odvesims »

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TEdit accepting non-numeric values
« Reply #1 on: August 10, 2017, 04:35:54 pm »
In the restrictions tab of the OI you can see that this feature only works on Windows.
The other WS don't support it AFAIK.

Maybe you can use a TSpinEdit, or a TMaskEdit as an alternative?

Bart

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: TEdit accepting non-numeric values
« Reply #2 on: August 10, 2017, 05:53:41 pm »
Fortunately it's not needed. The normal way is much more individually adjustable...  :)

Code: Pascal  [Select][+][-]
  1. Procedure TForm1.Edit1KeyPress(Sender: TObject; Var Key: Char);
  2.  Begin
  3.   If Not (Key In ['0'..'9', DecimalSeparator, #8, #13])
  4.   Then Key:= #0;
  5.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TEdit accepting non-numeric values
« Reply #3 on: August 10, 2017, 06:49:39 pm »
That might disable the delete key on some widgetsets.
It will also not avoid pasting text in the control (neither does TSpinEdit), which is handled correctly in TMaskEdit (with the correct mask).

Bart

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: TEdit accepting non-numeric values
« Reply #4 on: August 10, 2017, 08:05:52 pm »
Quote
That might disable the delete key on some widgetsets.
Really... that would be unhandy...  :P

Quote
It will also not avoid pasting text in the control ...
True... but that's easy, isn't it...  :)

Code: Pascal  [Select][+][-]
  1. Procedure TForm1.Edit1KeyDown(Sender: TObject; Var Key: Word;
  2.                               Shift : TShiftState);
  3.  Begin
  4.   If (ssSHIFT In Shift)
  5.   Then
  6.    Begin
  7.     //.... some other keys...
  8.  
  9.     If Key = VK_INSERT Then Key:= 0;  // uses LCLType
  10.    End;
  11.  End;
  12.  
  13.  
  14. Procedure TForm1.Edit1ContextPopup(Sender: TObject; MousePos: TPoint;
  15.                                    Var Handled: Boolean);
  16.  Begin
  17.   Handled:= True; // kill the menu or create your own...
  18.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TEdit accepting non-numeric values
« Reply #5 on: August 10, 2017, 10:12:47 pm »
That's not very nice.
Now the user cannot even paste correct input.

Bart

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: TEdit accepting non-numeric values
« Reply #6 on: August 11, 2017, 01:06:39 am »
Yes, true, but I don't think that's a problem for small things like DATE, TIME and something like that...

If you really need to copy & paste then what about this:
(You will get all the numbers from the clipboard...  :D)
Code: Pascal  [Select][+][-]
  1. {$R *.lfm}
  2.  USES ClipBrd;
  3.  
  4.  
  5. Procedure ClipbrdToNumber(AEdit: TEdit);
  6.   Var
  7.    strIn,
  8.    strOut: String;
  9.    i     : Integer;
  10.  Begin
  11.   If ClipBoard.HasFormat(CF_Text)
  12.   Then
  13.    Begin
  14.     strIn:= ClipBoard.AsText;
  15.  
  16.     For i:= 1 To Length(strIn)
  17.     Do
  18.      Begin
  19.       If Pos(strIn[i], '1234567890') <> 0
  20.       Then strOut:= strOut + strIn[i];
  21.      End;
  22.  
  23.     AEdit.Text:= AEdit.Text + strOut;
  24.     AEdit.SelStart:= Length(AEdit.Text);
  25.    End;
  26.  End;
  27.  
  28.  
  29. Procedure TForm1.Edit1KeyDown(Sender: TObject; Var Key: Word;
  30.                               Shift : TShiftState);
  31.  Begin
  32.   If (ssSHIFT In Shift)
  33.   Then
  34.    Begin
  35.     //...
  36.  
  37.     If Key = VK_INSERT
  38.     Then
  39.      Begin
  40.       Key:= 0;
  41.       ClipBrdToNumber(Edit1);
  42.      End;
  43.    End;
  44.  End;
  45.  
  46.  
  47. Procedure TForm1.Edit1KeyPress(Sender: TObject; Var Key: Char);
  48.  Begin
  49.   If Not (Key In ['0'..'9', #8, #13])
  50.   Then Key:= #0;
  51.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: TEdit accepting non-numeric values
« Reply #7 on: August 11, 2017, 01:24:02 am »
Yes, true, but I don't think that's a problem for small things like DATE, TIME and something like that...

If you really need to copy & paste then what about this:
(You will get all the numbers from the clipboard...  :D )
That's a start, a false start but a start. You need 2main changes
  1) accept the decimal seperator
  2) check the cursor's position and/or selection to determine if it is acceptable to paste that number.
and if the numeric edit has some sort of build in validation (min/max value) you need to make sure that after the paste it still passes that validation or reject the paste action.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: TEdit accepting non-numeric values
« Reply #8 on: August 11, 2017, 05:19:14 am »
@taazz:
Thanks, yeah.. it's much better now...

Validation... I normally do the validation after VK_RETURN or ButtonClick, the user maybe wants to do some editing after paste... ???

(Insert is not very fast, but in this case...  :D)
Code: Pascal  [Select][+][-]
  1. Procedure ClipbrdTxtToNumber(aEdit: TEdit; booDecimal: Boolean);
  2.   Var
  3.    strIn,
  4.    strOut,
  5.    strDecimal  : String;
  6.  
  7.    i, iSelStart: Integer;
  8.  Begin
  9.   If ClipBoard.HasFormat(CF_Text)
  10.   Then
  11.    Begin
  12.     strIn:= ClipBoard.AsText;
  13.  
  14.     If booDecimal
  15.     Then strDecimal:= DecimalSeparator
  16.     Else strDecimal:= '';
  17.  
  18.     For i:= 1 To Length(strIn)
  19.     Do
  20.      Begin
  21.       If Pos(strIn[i], '1234567890' + strDecimal) <> 0
  22.       Then strOut:= strOut + strIn[i];
  23.      End;
  24.  
  25.     If aEdit.SelLength > 0 Then aEdit.SelText:= '';
  26.  
  27.     strIn    := aEdit.Text;
  28.     iSelStart:= aEdit.SelStart;
  29.  
  30.     Insert(strOut, strIn, aEdit.SelStart+1);
  31.  
  32.     aEdit.Text    := strIn;
  33.     aEdit.SelStart:= iSelStart + Length(strOut);
  34.    End;
  35.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: TEdit accepting non-numeric values
« Reply #9 on: August 11, 2017, 05:38:11 am »
This way CTRL+V and SHIFT+INSERT is working...  :D

Code: Pascal  [Select][+][-]
  1. Procedure TForm1.Edit1KeyDown(Sender: TObject; Var Key: Word;
  2.                               Shift : TShiftState);
  3.  Begin
  4.   If (ssCTRL In Shift)
  5.   Then
  6.    Begin
  7.     If Key = VK_V
  8.     Then
  9.      Begin
  10.       Key:= 0;
  11.       ClipBrdTxtToNumber(Edit1, True);
  12.      End;
  13.  
  14.     //...
  15.    End;
  16.  
  17.  
  18.   If (ssSHIFT In Shift)
  19.   Then
  20.    Begin
  21.     //...
  22.  
  23.     If Key = VK_INSERT
  24.     Then
  25.      Begin
  26.       Key:= 0;
  27.       ClipBrdTxtToNumber(Edit1, True);
  28.      End;
  29.    End;
  30.  End;
  31.  
  32.  
  33. Procedure TForm1.Edit1KeyPress(Sender: TObject; Var Key: Char);
  34.  Begin
  35.   If Not (Key In ['0'..'9', DecimalSeparator, #8, #13])
  36.   Then Key:= #0;
  37.  End;
  38.  
  39.  
  40. Procedure TForm1.Edit1ContextPopup(Sender: TObject; MousePos: TPoint;
  41.                                    Var Handled: Boolean);
  42.  Begin
  43.   Handled:= True;
  44.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

Bart

  • Hero Member
  • *****
  • Posts: 5290
    • Bart en Mariska's Webstek
Re: TEdit accepting non-numeric values
« Reply #10 on: August 11, 2017, 02:21:25 pm »
No need to test for ClipBoard.HasFormat(CF_Text).
ClipBoard.AsText will be empty string if ClipBoard.HasFormat(CF_Text) is False.

Bart

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: TEdit accepting non-numeric values
« Reply #11 on: August 12, 2017, 07:22:15 am »
Thanks Bart.. didn't think about that...  :)
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

odvesims

  • Full Member
  • ***
  • Posts: 176
Re: TEdit accepting non-numeric values
« Reply #12 on: August 14, 2017, 02:20:55 pm »
Fortunately it's not needed. The normal way is much more individually adjustable...  :)

Code: Pascal  [Select][+][-]
  1. Procedure TForm1.Edit1KeyPress(Sender: TObject; Var Key: Char);
  2.  Begin
  3.   If Not (Key In ['0'..'9', DecimalSeparator, #8, #13])
  4.   Then Key:= #0;
  5.  End;

All observations are valid, so I appreciate everyone who put their input. This tiny bit of code does exactly what I need right now. Thanks RAW :)

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: [SOLVED] TEdit accepting non-numeric values
« Reply #13 on: August 15, 2017, 03:03:34 am »
Final version...  :D
A static array is faster than "POS"...
"INSERT" used or not doesn't really matter...

1.000 characters:
"POS"-version 16 ms
"Array"-version 0 ms

500.000 characters:
"POS"-version 1050 ms
"Array"-version 50 ms
 
1.000.000 characters:
"POS"-version 2.100 ms
"Array"-version 80 ms

Code: Pascal  [Select][+][-]
  1. Procedure ClipbrdNumbers(aEdit: TEdit; booDecimal: Boolean);
  2.   Var
  3.    strPaste,
  4.    strNum,
  5.    strEdit,
  6.    strOut: String;
  7.  
  8.    arrCharNum: Array[0..10] Of Char =
  9.                ('1','2','3','4','5','6','7','8','9','0',',');
  10.    i, iNum,
  11.    iCursor,
  12.    iRange: Integer;
  13.  Begin
  14.   strPaste:= ClipBoard.AsText;
  15.    If strPaste = '' Then Exit;
  16.  
  17.   If aEdit.SelLength > 0 Then aEdit.SelText:= '';
  18.    strEdit:= aEdit.Text;
  19.    iCursor:= aEdit.SelStart;
  20.  
  21.   If booDecimal
  22.   Then
  23.    Begin
  24.     arrCharNum[10]:= FormatSettings.DecimalSeparator;
  25.     iRange:= 0;
  26.    End
  27.   Else iRange:= -1;
  28.  
  29.   For i:= 1 To Length(strPaste)
  30.   Do
  31.    Begin
  32.     For iNum:= 0 To High(arrCharNum)+iRange
  33.     Do
  34.      Begin
  35.       If strPaste[i] = arrCharNum[iNum]
  36.       Then strNum:= strNum + strPaste[i];
  37.      End;
  38.    End;
  39.  
  40.   For i:= 1 To iCursor
  41.   Do strOut:= strOut + strEdit[i];
  42.  
  43.   strOut:= strOut + strNum;
  44.  
  45.   For i:= iCursor+1 To Length(strEdit)
  46.   Do strOut:= strOut + strEdit[i];
  47.  
  48.   aEdit.Text    := strOut;
  49.   aEdit.SelStart:= iCursor + Length(strNum);
  50.  End;
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

 

TinyPortal © 2005-2018