Lazarus

Programming => General => Topic started by: tatamata on February 15, 2014, 12:47:14 pm

Title: autoscrolling TMemo programatically
Post by: tatamata on February 15, 2014, 12:47:14 pm
I want to log a program's activities in a vertically scrollable Memo.
when number of lines excedes the window, the memo does not scroll automatically.
how to do it programatically?
Title: Re: autoscrolling TMemo programatically
Post by: Michl on February 15, 2014, 01:32:53 pm
I can not confirm that bevaior. If I add a line in that memo, it scrolls automatic to the last entry.

For example, use a empty form, with a memo (Scrollbars=ssAutoVertical) and a timer:
Code: [Select]
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Memo1.Lines.Add('Test '+IntToStr(Random(1000)));
end;
I use Win7 64bit, tested Lazarus 1.0.14 and 1.3Trunc - same behavior.
Title: Re: autoscrolling TMemo programatically
Post by: howardpc on February 15, 2014, 01:41:05 pm
With which widgetset do you see this behaviour? On Windows whether Scrollbars=ssVertical or
ScrollBars=ssAutoVertical the memo autoscrolls when the caret is about to disappear below the last visible memo line.
Title: Re: autoscrolling TMemo programatically
Post by: tatamata on February 15, 2014, 01:42:05 pm
With which widgetset do you see this behaviour? On Windows whether Scrollbars=ssVertical or
ScrollBars=ssAutoVertical the memo autoscrolls when the caret is about to disappear below the last visible memo line.
this is Linux, gtk2.
Title: Re: autoscrolling TMemo programatically
Post by: Michl on February 15, 2014, 02:27:08 pm
Not nice, but set SelStart should work:
Code: [Select]
  Memo1.SelStart := Length(Memo1.Lines.Text);

Maybe you can take a Listbox, there you can make something like:
Code: [Select]
  Listbox1.Items.Add('...');
  Listbox1.ItemIndex:=Listbox1.Items.Count-1;
Title: Re: autoscrolling TMemo programatically
Post by: Rails on February 15, 2014, 02:59:04 pm
Here's a quick and dirty that will make it scroll.   :)

Code: [Select]

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Memo1.Lines.Add('Test '+IntToStr(Random(1000)));
  Memo1.VertScrollBar.Position:=1000; 
end; 

Just set the memo's scrollbars to ssAuto and add the line setting the scrollbar's vertical position to something suitably high.

Tested on Linux/GTK-2
Title: Re: autoscrolling TMemo programatically
Post by: Michl on February 15, 2014, 07:50:51 pm
Just set the memo's scrollbars to ssAuto and add the line setting the scrollbar's vertical position to something suitably high.
This was my first intention but it works not on Win7, also difference.

Set SelStart or SendMessages works to change a memotextposition:
Code: [Select]
  SendMessage(Memo1.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
  SendMessage(Memo1.Handle, WM_VSCROLL, SB_LINEUP, 0);
  SendMessage(Memo1.Handle, WM_VSCROLL, SB_TOP, 0);
  SendMessage(Memo1.Handle, WM_VSCROLL, SB_BOTTOM, 0);
  SendMessage(Memo1.Handle, WM_VSCROLL, SB_PAGEDOWN, 0);
  SendMessage(Memo1.Handle, WM_VSCROLL, SB_PAGEUP, 0);
  ...
Title: Re: autoscrolling TMemo programatically
Post by: tatamata on February 15, 2014, 08:35:25 pm
With which widgetset do you see this behaviour? On Windows whether Scrollbars=ssVertical or
ScrollBars=ssAutoVertical the memo autoscrolls when the caret is about to disappear below the last visible memo line.
this is Linux, gtk2.
Hm, in Windows (even in Wine emulator) it works good...
So, seems to be widget-specific problem?

Tried all proposed solutions here, but it doesn't work...
Title: Re: autoscrolling TMemo programatically
Post by: Rails on February 15, 2014, 09:25:56 pm

Hm, in Windows (even in Wine emulator) it works good...
So, seems to be widget-specific problem?

Tried all proposed solutions here, but it doesn't work...

Are you saying that adding the auto scrollbars with  yourmemoname.VertScrollBar.Position := 1000  following each line written to the memo doesn't work in Linux GTK-2?

Title: Re: autoscrolling TMemo programatically
Post by: tatamata on February 15, 2014, 09:48:27 pm

Hm, in Windows (even in Wine emulator) it works good...
So, seems to be widget-specific problem?

Tried all proposed solutions here, but it doesn't work...

Are you saying that adding the auto scrollbars with  yourmemoname.VertScrollBar.Position := 1000  following each line written to the memo doesn't work in Linux GTK-2?

Ok, look the procedure, maybe you can see an error?
This procedure should just add a line to Memo, show it and scroll down if needed...I don't know, what am I overlooking here?
Commented is everything I tried so far...

Code: [Select]
procedure LogMRP(AString: String);
begin
  with FormMain do begin
    Refresh;
    //MemoMRPLog.Append(AString);
    MemoMRPLog.Lines.Add(AString);
    //MemoMRPLog.ScrollBy(0, 1);
    //MemoMRPLog.SelStart:=Length(FormMain.MemoMRPLog.Lines.Text);
    MemoMRPLog.VertScrollBar.Position:=1000;
    //MemoMRPLog.Refresh;
    //Refresh;
  end;
end;
Title: Re: autoscrolling TMemo programatically
Post by: segfault on April 15, 2019, 01:00:46 pm
I know this is an old thread, but I have a memo of FIXED length which I want to be scrolled HORIZONTALLY and I'm not sure how to do it. I have scollbars set to ssAutohorizontal and am adding numbers to each memo line and want the memo to be moved horizontally when the line exceeds the width of the memo. Thanks.
Title: Re: autoscrolling TMemo programatically
Post by: han on October 17, 2019, 07:05:53 pm
I don't have a solution for horizontal but vertical the only solution which worked for me in Linux:
Code: [Select]
  {$IFDEF LINUX}
  // scroll down:
    Memo2.SelStart:=Length(Memo2.lines.Text);
    Memo2.VertScrollBar.Position:=1000000;
  {$ELSE }
  {$ENDIF}   

or one line less

Code: [Select]
  {$IFDEF LINUX}
  // scroll down:
    Memo2.SelStart:=Length(Memo2.lines.Text)-1;
    Memo2.VertScrollBar.Position:=1000000;
  {$ELSE }
  {$ENDIF}   
Title: Re: autoscrolling TMemo programatically
Post by: sallecta on November 20, 2019, 03:22:23 am
Yet another hack to scroll  vertical scroll bar to bottom.

Code: Pascal  [Select]
  1. memo1.Append('some string'+LineEnding);
  2. memo1.SelStart:=memo1.Lines.Text.Length-1;
  3. memo1.SelLength:=1;
  4. memo1.ClearSelection;