Recent

Author Topic: [Solved] Preserving TEdit cursor position etc.  (Read 753 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 3289
[Solved] Preserving TEdit cursor position etc.
« on: September 24, 2021, 10:07:48 am »
I've got a form with a TEdit into which I occasionally want to enter text, and a frame into which monitoring information is being written asynchronously by a background thread via Synchronize() or QueueAsyncCall().

When monitoring information is written, the focus moves away from the TEdit. I can transfer it back using the form's ActiveControl property, but at that point the cursor is placed at the left of the text being entered and I presume that other state is destroyed.

Is there any way of saving the edit state? I've tried saving and restoring CaretPos without success.

MarkMLl
« Last Edit: September 24, 2021, 11:52:00 am by MarkMLl »
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

winni

  • Hero Member
  • *****
  • Posts: 2717
Re: Preserving TEdit cursor position etc.
« Reply #1 on: September 24, 2021, 10:18:48 am »
Hi!

The cursor position of  a Tedit can be read and set by Edit.selStart

Code: Pascal  [Select][+][-]
  1. var Cpos : integer;
  2. ...
  3. Cpos := Edit.SelStart;
  4. ...
  5. Edit.SelStart := Cpos;
  6.  

SelStart is zero based - to set the  cursor before the first char .

Winni

MarkMLl

  • Hero Member
  • *****
  • Posts: 3289
Re: Preserving TEdit cursor position etc.
« Reply #2 on: September 24, 2021, 10:41:13 am »
No change, the cursor always zips back to the left. Code looks something like this

Code: Pascal  [Select][+][-]
  1. procedure TFormPSTalk.MonitorHex(const message: string; sending: boolean);
  2.  
  3. var
  4.   i: integer;
  5.   savedControl: TWinControl;
  6. //  savedCaret: TPoint;
  7.   savedSelStart, savedSelLength: integer;
  8.  
  9. begin
  10.   savedControl := ActiveControl;
  11.   if ActiveControl = EditMessage then begin
  12. //    savedCaret := EditMessage.CaretPos;
  13.     savedSelStart := EditMessage.SelStart;
  14. //    savedSelLength := EditMessage.SelLength;
  15.   end;
  16.   for i := 1 to Length(message) do
  17.     MonitorHex(Ord(message[i]), sending);
  18.  
  19. (* Crude, but ensures that the final BCC or CRC byte of a message is always     *)
  20. (* displayed immediately. In practice since no interactive facilities are being *)
  21. (* used it looks as though the cursor is never displayed, which means we don't  *)
  22. (* have to waste time turning it off (which doesn't force an update).           *)
  23.  
  24.   FrameTerminalDisplay1.Cursor(true);
  25.   ActiveControl := savedControl;
  26.   if ActiveControl = EditMessage then begin
  27. //    EditMessage.CaretPos := savedCaret
  28.     EditMessage.SelStart := savedSelStart;
  29. //    EditMessage.SelLength := savedSelLength
  30.   end
  31. end { TFormPSTalk.MonitorHex } ;
  32.  

If I remove the monitoring stuff in the middle the cursor stays at the end of the text being edited.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: Preserving TEdit cursor position etc.
« Reply #3 on: September 24, 2021, 10:51:24 am »
Maybe TRecall?
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

MarkMLl

  • Hero Member
  • *****
  • Posts: 3289
Re: Preserving TEdit cursor position etc.
« Reply #4 on: September 24, 2021, 11:08:09 am »
Something like this?

Code: Pascal  [Select][+][-]
  1. var
  2.   recall: TRecall;
  3. ...
  4.     recall := TRecall.Create(TEdit.Create(nil), EditMessage);
  5. ...
  6.     recall.Destroy
  7.  

I get a runtime "Cannot assign a TEdit to a TEdit" at the Create :-(

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

GetMem

  • Hero Member
  • *****
  • Posts: 3493
Re: Preserving TEdit cursor position etc.
« Reply #5 on: September 24, 2021, 11:18:50 am »
The following code works fine with Lazarus Trunk/FPC 3.2.0.
Code: Pascal  [Select][+][-]
  1. //...
  2.   TForm1 = class(TForm)
  3.     Edit1: TEdit;
  4.   private
  5.      FSelStart: Integer;
  6.      FSelLength: Integer;
  7.   public
  8.   end;  
  9.  
  10. //save state
  11.   FSelStart := Edit1.SelStart;
  12.   FSelLength := Edit1.SelLength;  
  13.  
  14. //restore state
  15.   Edit1.SetFocus;
  16.   Edit1.SelStart := FSelStart;
  17.   Edit1.SelLength := FSelLength;
  18.   Edit1.SelStart := FSelStart;
 

winni

  • Hero Member
  • *****
  • Posts: 2717
Re: Preserving TEdit cursor position etc.
« Reply #6 on: September 24, 2021, 11:36:08 am »
Hi!

Maybe empty the evnt queue:


Code: Pascal  [Select][+][-]
  1.  ActiveControl := savedControl;
  2.  application.processMessages;  /// <---- !!!!
  3. if ActiveControl = EditMessage then begin
  4.     EditMessage.SelStart := savedSelStart;
  5.   end

Winni

MarkMLl

  • Hero Member
  • *****
  • Posts: 3289
Re: Preserving TEdit cursor position etc.
« Reply #7 on: September 24, 2021, 11:51:43 am »
Still zips back to the left with Lazarus 2.0.12 and FPC 3.2.0.

Ditto trunk which identifies itself as 2.3.0 SVN r65280.

The important info that I should have included is that this is Debian x86_64 using gtk2.

I find that if I switch to Qt5 I don't get the problem (but there are other UI problems which make it an undesirable solution).

I suspect that this is something I'm going to have to live with, at least until gtk3 is usable.

I find that if I use Winni's suggestion of an APM before restoring the selection state it appears to work, but it definitely requires that restoration of gtk2 and even Qt5 benefits from it.

:-)

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 10929
Re: Preserving TEdit cursor position etc.
« Reply #8 on: September 24, 2021, 01:15:58 pm »
Something like this?

Code: Pascal  [Select][+][-]
  1. var
  2.   recall: TRecall;
  3. ...
  4.     recall := TRecall.Create(TEdit.Create(nil), EditMessage);
  5. ...
  6.     recall.Destroy
  7.  

I get a runtime "Cannot assign a TEdit to a TEdit" at the Create :-(

MarkMLl
It should work with the existing instance?
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

MarkMLl

  • Hero Member
  • *****
  • Posts: 3289
Re: Preserving TEdit cursor position etc.
« Reply #9 on: September 24, 2021, 02:09:06 pm »
It should work with the existing instance?

I'm stymied by the lack of examples. In any event it looks as though it's the APM which is key.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018