Lazarus

Programming => Packages and Libraries => RichMemo => Topic started by: AndyJonson on April 30, 2017, 03:49:15 am

Title: Redo and first/last visible line
Post by: AndyJonson on April 30, 2017, 03:49:15 am
Hi All!

1) Can I call "redo" programical?
2) Can I get first and last visible line in Lazarus? (in Delphi I can do it with WinAPI)
Title: Re: Redo and first/last visible line
Post by: skalogryz on April 30, 2017, 04:22:53 am
1) with r5844
There're Redo() method and CanRedo property

2) what WinAPI call do you use in Delphi?
In RichMemo, there's CharAtPos (http://wiki.freepascal.org/RichMemo#CharAtPos) available.
It gives you a character index in the text. So it's up to your how to interpret the value.
Title: Re: Redo and first/last visible line
Post by: AndyJonson on April 30, 2017, 06:13:49 am
1) thanks!!! cool!!! :)

2) thanks! now I can get position of some symbol in first and last visible line. But how can I get line number from position?
...of course I can put cursor to this position and get line number with RichMemo1.CaretPos.y and then put cursor position back to old position... but... it is not good!
I try/want draw "map" of text - color line after vertical scroll with cursor position and screen pos.
(in old program in Delphi I did it with WinApi in one command/function without "blink")
Title: Re: Redo and first/last visible line
Post by: skalogryz on April 30, 2017, 06:52:25 am
2) thanks! now I can get position of some symbol in first and last visible line. But how can I get line number from position?
That depends on what you'd call "a line".
The line could be considered:
* either a paragraph (all text until line-break character is met - is a line)
* a text, that stays on the same vertical position from left side to the right side of the document.
The difference between these two, is obvious when word-wrap is enabled.
I.e. a very long paragraph can be broken among multiple lines on the screen.

...of course I can put cursor to this position and get line number with RichMemo1.CaretPos.y and then put cursor position back to old position... but... it is not good!
You don't have to move the cursor around.
Just do
RichMemo1.CharAtPos(0,0) - this is the top (left-most) character.
then do
RichMemo1.CharAtPos(RichMemo1.ClientHeight,0) - this is the bottom character.

(in old program in Delphi I did it with WinApi in one command/function without "blink")
so what WinApi command did you use?
EM_GETFIRSTVISIBLELINE (https://msdn.microsoft.com/en-us/library/windows/desktop/bb761574(v=vs.85).aspx) ? you could still use it with RichMemo
Code: Pascal  [Select]
  1.   ln:=SendMessage(RichMemo1.Handle, EM_GETFIRSTVISIBLELINE,0,0);
  2.  
Title: Re: Redo and first/last visible line
Post by: AndyJonson on April 30, 2017, 09:52:01 am
>> That depends on what you'd call "a line".
>> The line could be considered:
>> * either a paragraph (all text until line-break character is met - is a line)
>> * a text, that stays on the same vertical position from left side to the right side of the document.
I try get "text line"! without paragraph.

and I try not use WinAPI! Later I will try to compile this in Linux/Mac! Not shure that I can do it with "SendMessage".

now i use:
Code: Pascal  [Select]
  1.       RichMemo1.Lines.BeginUpdate;
  2.  
  3.       selPosOld := RichMemo1.SelStart;
  4.       selLenOld := RichMemo1.SelLength;
  5.  
  6.       RichMemo1.SelStart:=RichMemo1.CharAtPos(0,0);
  7.       y1 := RichMemo1.CaretPos.y;
  8.  
  9.       RichMemo1.SelStart:=RichMemo1.CharAtPos(0,RichMemo1.ClientHeight);
  10.       y2 := RichMemo1.CaretPos.y;
  11.  
  12.       RichMemo1.SelStart := selPosOld;
  13.       RichMemo1.SelLength := selLenOld;
  14.  
  15.       RichMemo1.Lines.EndUpdate;
  16.  
but it move scroll.  :'(

If it is not impossible without WinApi, I will refuse this idea (in this month/year)... But I need to now!
Title: Re: Redo and first/last visible line
Post by: skalogryz on May 02, 2017, 04:29:54 am
hmm... scroll bars are acting weird, but try this!
Code: Pascal  [Select]
  1.   RichMemo1.VertScrollBar.Smooth:=true;
  2.   vs:=RichMemo1.VertScrollBar.Position;
  3.   RichMemo1.Lines.BeginUpdate;
  4.   try
  5.     selPosOld := RichMemo1.SelStart;
  6.     selLenOld := RichMemo1.SelLength;
  7.  
  8.     RichMemo1.SelStart:=RichMemo1.CharAtPos(0,0);
  9.     y1 := RichMemo1.CaretPos.y;
  10.  
  11.     RichMemo1.SelStart:=RichMemo1.CharAtPos(0,RichMemo1.ClientHeight);
  12.     y2 := RichMemo1.CaretPos.y;
  13.  
  14.     RichMemo1.SelStart := selPosOld;
  15.     RichMemo1.SelLength := selLenOld;
  16.   finally
  17.     RichMemo1.Lines.EndUpdate;
  18.     RichMemo1.VertScrollBar.Position:=vs;
  19.   end;
  20.  
...hmm, it feels like TRichMemo should not rely on LCL Memo scrollbars and must implement its own (for Windows widgetset).
Position for TMemo in Win32 is a line #, where for RichEdit it's a pixel.