Recent

Author Topic: TEdit.Text already changed when KeyPress is triggered  (Read 530 times)

daniel_sap

  • Jr. Member
  • **
  • Posts: 64
TEdit.Text already changed when KeyPress is triggered
« on: November 02, 2024, 08:59:16 am »
Hi,
I observe different behaviour on Windows and MacOS when OnKeyPress event is triggered.

On Mac when the event is triggered the Text value is already changed and contains the Key which is pressed.
For example if I see in the edit the text 'Edit1' and then press the 'A' in the OnKeyPress event handler the 'A' is appended to the text. In Windows it is still the old text.

Is there any way to have the old value when key is pressed.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Edit1: TEdit;
  16.     procedure Edit1KeyPress(Sender: TObject; var Key: char);
  17.   private
  18.  
  19.   public
  20.  
  21.   end;
  22.  
  23. var
  24.   Form1: TForm1;
  25.  
  26. implementation
  27.  
  28. {$R *.lfm}
  29.  
  30. { TForm1 }
  31.  
  32. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
  33. begin
  34.   ShowMessage(Edit1.Text);
  35. end;
  36.  
  37. end.
  38.        

(I'm writing a custom control, so I want to handle it in the TCustomEdit descendant.)
Thanks

Lazarus 4.99 (rev main_4_99-369-g86db8d9f83) FPC 3.2.2 aarch64-darwin-cocoa
I built Lazarus for arm64 by myself. Not sure if this is related to that behaviour

jamie

  • Hero Member
  • *****
  • Posts: 6733
Re: TEdit.Text already changed when KeyPress is triggered
« Reply #1 on: November 02, 2024, 06:03:19 pm »
that event requires both the KeyDown and KeyUp so yes, it will be changed already.,.

Use the KeyDown even to make alterations
The only true wisdom is knowing you know nothing

Bart

  • Hero Member
  • *****
  • Posts: 5465
    • Bart en Mariska's Webstek
Re: TEdit.Text already changed when KeyPress is triggered
« Reply #2 on: November 02, 2024, 06:14:17 pm »
It's perfectly lega to use OnKeyPress to make changes (e.g. block certain keys).
Only after OnKeyPressed is processed the Text should be updated (e.g. the control should only then receive the key).

This should work as expected:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
  2. begin
  3.   if not (Key in ['0'..'9'] then
  4.     Key := #0
  5.   else
  6.     //just mess with the user's input for fun
  7.     Key := '9';
  8. end;

The result should be that whatever you type, it's either rejected, or converted to a '9'.
This can only happen because it's the altered Key that is received by the control, not the original Key.

If this sample code does not work on Cocoa, then that is a bug.

Bart

jamie

  • Hero Member
  • *****
  • Posts: 6733
Re: TEdit.Text already changed when KeyPress is triggered
« Reply #3 on: November 02, 2024, 07:51:09 pm »
It's perfectly lega to use OnKeyPress to make changes (e.g. block certain keys).
Only after OnKeyPressed is processed the Text should be updated (e.g. the control should only then receive the key).

This should work as expected:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
  2. begin
  3.   if not (Key in ['0'..'9'] then
  4.     Key := #0
  5.   else
  6.     //just mess with the user's input for fun
  7.     Key := '9';
  8. end;

The result should be that whatever you type, it's either rejected, or converted to a '9'.
This can only happen because it's the altered Key that is received by the control, not the original Key.

If this sample code does not work on Cocoa, then that is a bug.

Bart
You are correct, Sorry.
Jamie
The only true wisdom is knowing you know nothing

daniel_sap

  • Jr. Member
  • **
  • Posts: 64
Re: TEdit.Text already changed when KeyPress is triggered
« Reply #4 on: November 02, 2024, 09:12:31 pm »
Quote
It's perfectly lega to use OnKeyPress to make changes (e.g. block certain keys).
Only after OnKeyPressed is processed the Text should be updated (e.g. the control should only then receive the key).

This should work as expected:
Code: Pascal  [Select]

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
begin
  if not (Key in ['0'..'9'] then
    Key := #0
  else
    //just mess with the user's input for fun
    Key := '9';
end;

The result should be that whatever you type, it's either rejected, or converted to a '9'.
This can only happen because it's the altered Key that is received by the control, not the original Key.

If this sample code does not work on Cocoa, then that is a bug.

Bart

This is not working on MacOS. The text is changed prior to KeyPress execution and the Key is not used after that for updating the Text.
Even SelStart and SelLength are already updated

Code: Pascal  [Select][+][-]
  1. unit MainForm;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   TForm1 = class(TForm)
  15.     Edit1: TEdit;
  16.     Memo1: TMemo;
  17.     procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  18.     procedure Edit1KeyPress(Sender: TObject; var Key: char);
  19.     procedure Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  20.   private
  21.  
  22.   public
  23.  
  24.   end;
  25.  
  26. var
  27.   Form1: TForm1;
  28.  
  29. implementation
  30.  
  31. {$R *.lfm}
  32.  
  33. { TForm1 }
  34.  
  35. procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: char);
  36. begin
  37.   Memo1.Lines.Add('Key press: ' + Edit1.Text);
  38.   if not (Key in ['0'..'9']) then
  39.     Key := #0
  40.   else
  41.     //just mess with the user's input for fun
  42.     Key := '9';
  43.   Memo1.Lines.Add(Format('Selection SelStart: %d, SelCount: %d', [Edit1.SelStart, Edit1.SelLength]));
  44. end;
  45.  
  46. procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
  47. begin
  48.   Memo1.Lines.Add('Key Up: ' + Edit1.Text);
  49. end;
  50.  
  51. procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState
  52.   );
  53. begin
  54.   Memo1.Lines.Add('Key down: ' + Edit1.Text);
  55. end;
  56.  
  57. end.
  58.  

Bart

  • Hero Member
  • *****
  • Posts: 5465
    • Bart en Mariska's Webstek
Re: TEdit.Text already changed when KeyPress is triggered
« Reply #5 on: November 02, 2024, 10:07:20 pm »
@daniel_sap: Which version of Lazarus are you using?

If you are not using Lazarus main (4.99) could you try that?
If the issue is present on Lazarus main, then you should file a bugreport.

Since I don't have access to a Mac, I cannot reporduce this issue myself.

Bart

daniel_sap

  • Jr. Member
  • **
  • Posts: 64
Re: TEdit.Text already changed when KeyPress is triggered
« Reply #6 on: November 03, 2024, 07:36:10 am »
Quote
@daniel_sap: Which version of Lazarus are you using?

If you are not using Lazarus main (4.99) could you try that?
If the issue is present on Lazarus main, then you should file a bugreport.

Since I don't have access to a Mac, I cannot reporduce this issue myself.

Bart

I'm with Lazarus 4.99 (rev main_4_99-369-g86db8d9f83) FPC 3.2.2 aarch64-darwin-cocoa (I built Lazarus for arm64)
Not latest commit. ASAP will try to pull latest changes and try again

 

TinyPortal © 2005-2018