Recent

Author Topic: TMemo send to bottom or top  (Read 1185 times)

eldonfsr

  • Sr. Member
  • ****
  • Posts: 443
TMemo send to bottom or top
« on: September 27, 2022, 04:06:45 pm »
Hi sorry for topic i trying to play with Tmemo send by code to top or bottom but i don't see event like that caretpos don't show cursor there there another way to do king of movement on Tmemo...
 

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2006
  • Fifty shades of code.
    • Delphi & FreePascal
Re: TMemo send to bottom or top
« Reply #1 on: September 27, 2022, 04:16:14 pm »
I never tried but according to https://lazarus-ccr.sourceforge.io/docs/lcl/stdctrls/tcustomedit.caretpos.html you might be able to do something like this?
Code: Pascal  [Select][+][-]
  1. Memo1.CaretPos := 0; // jump to beginning
  2. Memo1.CaretPos := Length(Memo.Text); // jump to end
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

eldonfsr

  • Sr. Member
  • ****
  • Posts: 443
Re: TMemo send to bottom or top
« Reply #2 on: September 27, 2022, 04:28:14 pm »
Thanks but is not possible Tmemo.carretpos required Tpoint....

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: TMemo send to bottom or top
« Reply #3 on: September 27, 2022, 04:36:29 pm »
so what?

make TPoint variable, assign its fields, and then assign memo's caretpos


but WHAT do you really want to do?  http://xyproblem.info/

do you want to move caret (mere position of where user's keying new letters into memo would have the new text inserted) ? or scroll visible text?

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: TMemo send to bottom or top
« Reply #4 on: September 27, 2022, 04:38:27 pm »
Thanks but is not possible Tmemo.carretpos required Tpoint....

Well give it a TPoint then. I don't know.

This working example might help:

Code: Pascal  [Select][+][-]
  1. (* Append a line to the memo being use for status output, scrolling etc. as
  2.   appropriate.
  3. *)
  4. procedure TGuiTestForm.StatusAppendLine(const s: string);
  5.  
  6. const
  7.   limit= 8192;
  8.   slop= 128;
  9.  
  10. const
  11.   hasBeenVisible: boolean= false;       (* Static variable                      *)
  12.  
  13. var
  14.   caret: TPoint;
  15.   trimmedLines: integer;
  16.   forceToEnd: boolean;
  17.  
  18. begin
  19.   with MemoStatus do begin              (* Slightly simplified from Watchxxx,   *)
  20.     if Visible then                     (* idea is to keep the line the user    *)
  21.       hasBeenVisible := true;           (* is trying to look at visible.        *)
  22.     if hasBeenVisible then              (* Avoid "GetCaretPos called without handle" *)
  23.       caret := CaretPos
  24.     else begin
  25.       caret.X := 0;
  26.       caret.Y := 0
  27.     end;
  28.     trimmedLines := Lines.Count;        (* Visible for debugging                *)
  29.     forceToEnd := caret.Y >= trimmedLines - 1;
  30.     trimmedLines := 0;
  31.     try
  32.       if Lines.Count > limit + slop div 2 then begin
  33.         while Lines.Count > limit - slop div 2 do begin
  34.           Lines.Delete(0);
  35.           trimmedLines += 1;
  36.           if caret.Y > 0 then
  37.             caret.Y -= 1
  38.         end
  39.       end;
  40.     Lines.Append(s);
  41.     finally
  42.       if forceToEnd then
  43.         if Lines.Count > 0 then
  44.           caret.Y := Lines.Count - 1;
  45.       if hasBeenVisible then            (* Avoid "SetCaretPos called without handle" *)
  46.         CaretPos := caret
  47.     end
  48.   end
  49. end { TGuiTestForm.StatusAppendLine } ;
  50.  

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

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2006
  • Fifty shades of code.
    • Delphi & FreePascal
Re: TMemo send to bottom or top
« Reply #5 on: September 27, 2022, 05:26:24 pm »
Thanks but is not possible Tmemo.carretpos required Tpoint....
I do apology with this:
Code: Pascal  [Select][+][-]
  1. procedure JumpTop(const Memo: TMemo);
  2. var
  3.   tp: TPoint;
  4. begin
  5.   tp.X := 0;
  6.   tp.Y := 0;
  7.   Memo.CaretPos := tp;
  8.   Memo.VertScrollBar.Position := 0;
  9. end;
  10.  
  11. procedure JumpEnd(const Memo: TMemo);
  12. var
  13.   tp: TPoint;
  14. begin
  15.   tp.X := High(LongInt);
  16.   tp.Y := High(LongInt);
  17.   Memo.CaretPos := tp;
  18.   Memo.VertScrollBar.Position := Memo.VertScrollBar.Range - Memo.VertScrollBar.Page;
  19. end;
Use it like JumpTop(Memo1) or JumpEnd(Memo1)....
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2006
  • Fifty shades of code.
    • Delphi & FreePascal
Re: TMemo send to bottom or top
« Reply #6 on: September 27, 2022, 05:32:49 pm »
Code: Pascal  [Select][+][-]
  1.   if Memo.VertScrollBar.IsScrollBarVisible then
Maybe add this above my scrollbar to ensure nothing bad happen.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

eldonfsr

  • Sr. Member
  • ****
  • Posts: 443
Re: TMemo send to bottom or top
« Reply #7 on: September 27, 2022, 05:58:34 pm »
I don't know here my procedure but you can see image don't show bottom of Tmemo

procedure TForm_Main.SerialRxData(Sender: TObject);
Var tp:TPoint;
begin

  MDatas.Lines.BeginUpdate;
  MDatas.Lines.Text := MDatas.Lines.Text + Serial.ReadData;
  MDatas.Lines.EndUpdate;
  tp.x := MDatas.Lines.Count-1;
  tp.Y:= 0 ;
  MDatas.CaretPos:= tp;
end;


KodeZwerg

  • Hero Member
  • *****
  • Posts: 2006
  • Fifty shades of code.
    • Delphi & FreePascal
Re: TMemo send to bottom or top
« Reply #8 on: September 27, 2022, 06:03:06 pm »
Use my methods and you have what you wanted.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Arioch

  • Sr. Member
  • ****
  • Posts: 421
Re: TMemo send to bottom or top
« Reply #9 on: September 27, 2022, 06:06:49 pm »
  tp.Y:= 0 ;

https://en.wikipedia.org/wiki/File:Cartesian-coordinate-system.svg

0-th line is which one?

ShowMessage(MEmo.Lines[0]) - gives what?

that is the string you scrolled to, probably. to scroll to bottom string, you probably have to set Y to the number of bottom string, or maybe to that number + 1
« Last Edit: September 27, 2022, 06:08:24 pm by Arioch »

eldonfsr

  • Sr. Member
  • ****
  • Posts: 443
Re: TMemo send to bottom or top
« Reply #10 on: September 27, 2022, 07:34:49 pm »
Thanks to everybody to replay to me Kore i put your code but some happend for moment show bottom but sadly change and go to top
Code: Pascal  [Select][+][-]
  1. procedure TForm_Main.SerialRxData(Sender: TObject);
  2. Var tp:TPoint;
  3. begin
  4.   if MDatas.VertScrollBar.Visible = false then begin
  5.      MDatas.VertScrollBar.Visible := true;
  6.   end;
  7.   MDatas.Lines.BeginUpdate;
  8.   MDatas.Lines.Text := MDatas.Lines.Text + Serial.ReadData;
  9.   MDatas.Lines.EndUpdate;
  10.   JumpEnd(MDatas);      
  11. end;
  12.  
  13.  
I put showmessage( Form_Main.Mdatas.lines[0]) but show empty message not I complete missing whats going on...

eldonfsr

  • Sr. Member
  • ****
  • Posts: 443
Re: TMemo send to bottom or top
« Reply #11 on: September 27, 2022, 08:47:07 pm »
Some thing happen when you send from serial.DataRead to Tmemo

just i made this chnage and works..
Code: Pascal  [Select][+][-]
  1.    Str:=Serial.ReadData;
  2.   MDatas.Lines.BeginUpdate;
  3. //  MDatas.Lines.Text := MDatas.Lines.Text + Str;
  4.   MDatas.Lines.Append(Str) ;
  5.   MDatas.Lines.EndUpdate;
  6.   JumpEnd(MDatas);      
  7.  

cdbc

  • Hero Member
  • *****
  • Posts: 995
    • http://www.cdbc.dk
Re: TMemo send to bottom or top
« Reply #12 on: September 30, 2022, 09:59:49 am »
Hi
Your question got me curious  %)
So I fiddled a bit and came up with this:
Code: Pascal  [Select][+][-]
  1. procedure ScrollMemoTo(const aMemo: TMemo; anOrigin: TSeekOrigin);
  2. var
  3.   NewCaretPos: TPoint;
  4.   HasBeenVisible: boolean = false;
  5. begin
  6.   if aMemo.Visible then HasBeenVisible:= true;
  7.   if HasBeenVisible then NewCaretPos:= aMemo.CaretPos { Avoid "GetCaretPos called without handle" }
  8.   else begin
  9.     NewCaretPos.X:= 0;
  10.     NewCaretPos.Y:= 0;
  11.   end; { the above is borrowed from MarkMLl, I couldn't make it work... }
  12.   case anOrigin of
  13.     soBeginning: begin { try to position caret a the beginning of text }
  14.                    { trick the memo into scrolling to the beginning :o) }
  15.                    aMemo.SelStart:= 0; //UTF8Length(aMemo.Text)-5;
  16. //                   aMemo.SelLength:= 5; // well it works without
  17. //                   aMemo.SelLength:= 0; // well it works without
  18.                  end;
  19.     soCurrent:   aMemo.SelStart:= NewCaretPos.X; { leave NewCaretPos alone, it has been set }
  20.     soEnd:       begin { try to position caret a the end of text }
  21.                    { trick the memo into scrolling to the end :o) }
  22. //                   aMemo.SelStart:= UTF8Length(aMemo.Text)-5; // well it works without
  23. //                   aMemo.SelLength:= 5; // well it works without
  24.                    aMemo.SelStart:= UTF8Length(aMemo.Text); { this does the trick :o) }
  25.                    { another option would be:
  26.                      if aMemo.VertScrollBar.Visible then
  27.                        aMemo.VertScrollBar.Position:= aMemo.VertScrollBar.Range; }
  28.                  end;
  29.   end;
  30. exit;
  31.   { should persist by way of "SetCaretPos" }             //excerpt from MarkMLl
  32.   if HasBeenVisible then aMemo.CaretPos:= NewCaretPos; { Avoid "SetCaretPos called without handle" }
  33. end;
  34. ...
  35. and call it like this:
  36. ScrollMemoTo(Memo1,soEnd);
  37.  
My first tries all went to H*** in a handbasket, then I started thinking...
UTF8Length was the answer  :P
Comments are very welcome  ;)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

jcmontherock

  • Full Member
  • ***
  • Posts: 234
Re: TMemo send to bottom or top
« Reply #13 on: September 30, 2022, 10:41:27 am »
more simply:
Code: Pascal  [Select][+][-]
  1. SendMessage(Memo1.Handle, EM_LINESCROLL, 0, Memo1.Lines.Count+5);
  2.  
Windows 11 UTF8-64 - Lazarus 3.2-64 - FPC 3.2.2

cdbc

  • Hero Member
  • *****
  • Posts: 995
    • http://www.cdbc.dk
Re: TMemo send to bottom or top
« Reply #14 on: September 30, 2022, 06:12:56 pm »
Hi
@jcmontherock: I was trying to remember this approach, but couldn't remember the message number EM_LINESCROLL, so i got selstart to work...
 ;)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

 

TinyPortal © 2005-2018