Recent

Author Topic: [SOLVED -- mostly] Show last line of TMemo after text change  (Read 2658 times)

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
[SOLVED -- mostly] Show last line of TMemo after text change
« on: April 29, 2023, 01:50:14 am »
Greetings everyone,

I have a TMemo that I'm using to show textual progress of a certain process.  Instead of using Append or Lines.Add I must use the following pattern:

Code: Pascal  [Select][+][-]
  1. Memo1.Text := Memo1.Text + 'Deleting file...';
  2.  
  3. // processing happens here
  4.  
  5. If ProcessFailed = False Then
  6.   Memo1.Text := Memo1.Text + 'Ok' + LineEnding
  7. Else
  8.   Memo1.Text := Memo1.Text + 'failed!' + LineEnding;
  9.  
  10. // scroll memo to bottom code here

I cannot use Append or Lines.Add in this scenario because I want the 'Ok' or 'failed' to be right after the 'Deleting file...'.  Unfortunately I cannot make the TMemo scroll to the bottom line after each line I add, no matter what I've tried.

I've tried other suggestions from the forums including using SetSelStart and SetSelLength, tried VertScrollBar.Position and SendMessage with EM_LINESCROLL and none of these scroll the TMemo to the last line.

Is there some technique I have not seen to accomplish this?

Thank you!  :D
« Last Edit: April 29, 2023, 08:42:06 am by willbprog9933 »
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Show last line of TMemo after text change
« Reply #1 on: April 29, 2023, 02:13:33 am »
I do not know about the scrolling (perhaps autoscroll ?) but why using memo.text := memo.text + 'whatever' ?

The memo has a lines property and that has a count member. With a little calculation (lines start with index 0) you can then directly access the last line in the memo, retrieve the text in that line, modify it to whatever your heart desire and store it back. As a bonus it is much quicker as well. In case it is not the last line in the memo but you do know where it is located then you can use the same technique (only using another index for the lines property).
« Last Edit: April 29, 2023, 02:15:49 am by TRon »
Today is tomorrow's yesterday.

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: Show last line of TMemo after text change
« Reply #2 on: April 29, 2023, 02:15:36 am »
The memo has a lines property and that has a count member. With a little calculation (lines start with index 0) you can then directly access the last line in the memo, retrieve the text in that line, modify it to whatever your heart desire and store it back. As a bonus it is much quicker as well. In case it is not the last line in the memo but you do knw where it is located ten you can use the same technique (only using another index for the lines property).

Hi TRon,

That sounds like a good idea.  I will try it out and post my results.

Thanks! :D
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

jamie

  • Hero Member
  • *****
  • Posts: 6989
Re: Show last line of TMemo after text change
« Reply #3 on: April 29, 2023, 02:22:18 am »
Looks like you are not on Windows, that message won't work.

You can move the Scroll position of the Memo vertical scroll bar to the size.

That should show the last lines, same as if you were to scroll manually,.
The only true wisdom is knowing you know nothing

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: Show last line of TMemo after text change
« Reply #4 on: April 29, 2023, 02:27:00 am »
The memo has a lines property and that has a count member. With a little calculation (lines start with index 0) you can then directly access the last line in the memo, retrieve the text in that line, modify it to whatever your heart desire and store it back. As a bonus it is much quicker as well. In case it is not the last line in the memo but you do know where it is located then you can use the same technique (only using another index for the lines property).

I tried this and it does not behave the way I want.  I used Append for 'Deleting...' then went back and changed the last line in Memo1.Lines to include the 'Ok' or 'failed' part and it just acts as if I used Append with the 'Ok' or 'failed' text.

Thanks anyway!  :)
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: Show last line of TMemo after text change
« Reply #5 on: April 29, 2023, 02:29:41 am »
Looks like you are not on Windows, that message won't work.

I am on Windows, but I would like this to be cross-platform as I use Linux mostly.

Quote
You can move the Scroll position of the Memo vertical scroll bar to the size.

That should show the last lines, same as if you were to scroll manually,.

This was one of the things I tried and it did not work.

What's frustrating is the carat never moves past the first character in the TMemo.  It never moves from there, not even for an instant.
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

jamie

  • Hero Member
  • *****
  • Posts: 6989
Re: Show last line of TMemo after text change
« Reply #6 on: April 29, 2023, 02:40:01 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   memo1.VertScrollBar.Position := Memo1.VertScrollBar.Size;
  4. end;                                                            
  5.  

If that does not work, then there is a widget issue.
do that after each time you add something.
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 6989
Re: Show last line of TMemo after text change
« Reply #7 on: April 29, 2023, 02:47:02 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button2Click(Sender: TObject);
  2. begin
  3.   If Memo1.Lines.Count > 50 Then Memo1.Lines.Delete(0);
  4.   Memo1.Lines.Add(TimeToStr(Now));
  5.   memo1.VertScrollBar.Position := Memo1.VertScrollBar.Size;
  6. end;                                                
  7.  

Another Test..
The only true wisdom is knowing you know nothing

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: Show last line of TMemo after text change
« Reply #8 on: April 29, 2023, 02:47:23 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   memo1.VertScrollBar.Position := Memo1.VertScrollBar.Size;
  4. end;                                                            
  5.  

Thanks again, but it's not working.  I took your code verbatim and it's not scrolling or moving the carat at all.  I even tried the carat position proc and it didn't work either.  I guess I'll just have to try something else or track down the source for the TMemo and see how they scroll after an Append / Lines.Add.

Thanks again! :)
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Show last line of TMemo after text change
« Reply #9 on: April 29, 2023, 02:48:30 am »
I tried this and it does not behave the way I want.  I used Append for 'Deleting...' then went back and changed the last line in Memo1.Lines to include the 'Ok' or 'failed' part and it just acts as if I used Append with the 'Ok' or 'failed' text.
Works for me tm

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   n: integer;
  4. begin
  5.   // do stuff
  6.   for n := 1 to 100 do
  7.   begin
  8.     Memo1.Lines.Add(n.ToString);
  9.  
  10.     {$IFDEF LINUX}
  11.     // scroll down:
  12.     Memo1.SelStart:=Length(Memo1.lines.Text);
  13.     Memo1.VertScrollBar.Position:=1000000;
  14.     {$ENDIF}
  15.     application.ProcessMessages;
  16.   end;
  17.   n := Memo1.Lines.Add('This is waiting ...');
  18.   {$IFDEF LINUX}
  19.   // scroll down:
  20.   Memo1.SelStart:=Length(Memo1.lines.Text);
  21.   Memo1.VertScrollBar.Position:=1000000;
  22.   {$ENDIF}
  23.   application.ProcessMessages;
  24.   sleep(6*1000);
  25.   Memo1.Lines[n] := Memo1.Lines[n] + ' OK';
  26. end;
  27.  


@jamie: widgetset issue.autoscroll (caret visible at all times) works on Windows not on gtk2 (hence my ifdef)
Today is tomorrow's yesterday.

jamie

  • Hero Member
  • *****
  • Posts: 6989
Re: Show last line of TMemo after text change
« Reply #10 on: April 29, 2023, 02:54:16 am »
What's this world coming to.

The only true wisdom is knowing you know nothing

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: Show last line of TMemo after text change
« Reply #11 on: April 29, 2023, 05:15:56 am »
What's this world coming to.

Sorry, guess I'll just deal with it.

(shrugs)

Thanks everyone anyway...
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: Show last line of TMemo after text change
« Reply #12 on: April 29, 2023, 08:41:11 am »
Just to help future searchers...

I found TMemo.ScrollBy() and tried that, and, no, didn't work either.  The TMemo just refuses to be told how to scroll, I guess.  While doing further research, I stumbled on clarification of what TRon suggested.  TRon suggested using Append, then changing the last line in the TMemo.  It didn't work when I tried it, but then found that you have to access that last line using TMemo.Lines.Strings[index].  That worked!  :D

So, in shorthand code...

Code: Pascal  [Select][+][-]
  1. Memo1.Append('Deleting file...');
  2.  
  3. // do processing here
  4.  
  5. If ProcessFailed = False Then
  6.   Memo1.Lines.Strings[Memo1.Lines.Count - 1] := Memo1.Lines.Strings[Memo1.Lines.Count - 1] + 'Ok'
  7. Else
  8.   Memo1.Lines.Strings[Memo1.Lines.Count - 1] := Memo1.Lines.Strings[Memo1.Lines.Count - 1] + 'failed';

So, not the prettiest solution, but TRon had the right idea, and Append does scroll the TMemo properly.  I made the last line modification code into a separate procedure so I didn't have to type all of that out repeatedly everywhere its needed.

Thanks everyone! :D
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

jamie

  • Hero Member
  • *****
  • Posts: 6989
Re: [SOLVED -- mostly] Show last line of TMemo after text change
« Reply #13 on: April 29, 2023, 02:59:28 pm »
BAC, are you multi-threading in your app?

EDIT

  I was just curious because it seems you have a lot of issues lately! :D
« Last Edit: April 29, 2023, 03:01:28 pm by jamie »
The only true wisdom is knowing you know nothing

willbprog9933

  • Jr. Member
  • **
  • Posts: 93
  • Big guy, tiny brain :P
    • BrainOut!
Re: [SOLVED -- mostly] Show last line of TMemo after text change
« Reply #14 on: April 29, 2023, 06:00:47 pm »
BAC, are you multi-threading in your app?

EDIT

  I was just curious because it seems you have a lot of issues lately! :D

Was this directed at me?  Sorry, don't know what "BAC" means...

Thanks!  :D
macOS, Linux, FreeBSD and sometimes OpenIndiana.

Blessed, loved and forgiven! :D

 

TinyPortal © 2005-2018