Hi
Your question got me curious
So I fiddled a bit and came up with this:
procedure ScrollMemoTo(const aMemo: TMemo; anOrigin: TSeekOrigin);
var
NewCaretPos: TPoint;
HasBeenVisible: boolean = false;
begin
if aMemo.Visible then HasBeenVisible:= true;
if HasBeenVisible then NewCaretPos:= aMemo.CaretPos { Avoid "GetCaretPos called without handle" }
else begin
NewCaretPos.X:= 0;
NewCaretPos.Y:= 0;
end; { the above is borrowed from MarkMLl, I couldn't make it work... }
case anOrigin of
soBeginning: begin { try to position caret a the beginning of text }
{ trick the memo into scrolling to the beginning :o) }
aMemo.SelStart:= 0; //UTF8Length(aMemo.Text)-5;
// aMemo.SelLength:= 5; // well it works without
// aMemo.SelLength:= 0; // well it works without
end;
soCurrent: aMemo.SelStart:= NewCaretPos.X; { leave NewCaretPos alone, it has been set }
soEnd: begin { try to position caret a the end of text }
{ trick the memo into scrolling to the end :o) }
// aMemo.SelStart:= UTF8Length(aMemo.Text)-5; // well it works without
// aMemo.SelLength:= 5; // well it works without
aMemo.SelStart:= UTF8Length(aMemo.Text); { this does the trick :o) }
{ another option would be:
if aMemo.VertScrollBar.Visible then
aMemo.VertScrollBar.Position:= aMemo.VertScrollBar.Range; }
end;
end;
exit;
{ should persist by way of "SetCaretPos" } //excerpt from MarkMLl
if HasBeenVisible then aMemo.CaretPos:= NewCaretPos; { Avoid "SetCaretPos called without handle" }
end;
...
and call it like this:
ScrollMemoTo(Memo1,soEnd);
My first tries all went to H*** in a handbasket, then I started thinking...
UTF8Length was the answer
Comments are very welcome
Regards Benny