Recent

Author Topic: TMemo, count lines  (Read 18587 times)

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: TMemo, count lines
« Reply #15 on: February 07, 2020, 11:05:55 pm »
Hello Winni,

thanks for the advice, I'll try!

"But anyway: working with Memos is not a good idea."
What is a better alternative?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TMemo, count lines
« Reply #16 on: February 08, 2020, 01:16:17 am »
Hi!

I'll try it again with this steamboat forum.

What do you want to do with the Memo?

If it is for a few words an some remarks a Memo is enough - but I would not invest to much enery and code in it to give it real editor functions.

If you are looking for some textengine then I would take the RichMemo component. It's a real richtext editor.

But If you need an editor for coding - then take synedit - the editor from the IDE.

Let's see how many reloads are needed to send this text ........

Winni
« Last Edit: February 08, 2020, 01:21:38 am by winni »

Thaddy

  • Hero Member
  • *****
  • Posts: 14198
  • Probably until I exterminate Putin.
Re: TMemo, count lines
« Reply #17 on: February 08, 2020, 08:48:22 am »
Property TForum.Attempts.Count
Specialize a type, not a var.

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: TMemo, count lines
« Reply #18 on: February 08, 2020, 10:35:59 am »
* Disable wordwrap. Now the visible lines and the Stringlist memo.lines go synchronus.

* Set the caret at the last char of the memo.text and ask the memo.caretpos.
Memo.selstart := UTF8Length(memo.text);
Now LineCount := caretpos.y div memo.Font.Height + 1
Did you just read the title and made this suggestion?

If you read the complete topic you'll see it's about adjusting the height of the TMemo when the lines are wrapped (autosize). It's not about 'counting lines'.

Now I'm not sure what kupferstecher is after exactly, but (s)he mentioned my snippet worked on Windows. And that snippet has nothing to do with counting lines.

Granted... The question wasn't really that clear so matbe kupferstecher can clarify it.


kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: TMemo, count lines
« Reply #19 on: February 08, 2020, 11:06:45 am »
Probably its the best I describe in detail what I try to achive:

I made myself a component to modally display forms embedded into the main window. The background of the main form is captured, gray shaded and the embedded form is displayed in the center. That part is already finished and works fine.
The component also should have a functionality like 'ShowMessage', i.e. the message text is centered in the main form. Attached a screenshot how it looks under Windows, as said, there it works with rvk's solution.
So what I need is to know the actual height of the text in the Memo so that I can do the size adjustment and centering.

If I have the (actual) number of lines instead of the height, I can easily calculate the height. But it also has to work when the Memo is not fully extended, but in a scrolling mode because of the limited area.

As you can see, the Memo is in ReadOnly configuration, the user still can mark and copy the text.

Regards~

rvk

  • Hero Member
  • *****
  • Posts: 6110
Re: TMemo, count lines
« Reply #20 on: February 08, 2020, 02:43:21 pm »
If I have the (actual) number of lines instead of the height, I can easily calculate the height. But it also has to work when the Memo is not fully extended, but in a scrolling mode because of the limited area.
Yes, having the count of lines doesn't work for height if you have wrapped enabled.
You'll need to calculate the height yourself.

My earlier solution only works on Windows because it directly queries the Windows-component for the height.

On Linux/Mac you might have better luck just trying DrawText (on a temporary canvas) and seeing what the drawn size is.

This post does that:
https://forum.lazarus.freepascal.org/index.php?topic=22531.msg283352#msg283352

Another option would be to AdjustSize for a temp component but I'm not sure if that works for wrapped lines. Just try it if the other doesn't work.
https://forum.lazarus.freepascal.org/index.php/topic,22531.msg283593.html#msg283593

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TMemo, count lines
« Reply #21 on: February 08, 2020, 02:46:05 pm »
Hi!

I would do it this way:

make Memo invisible
Assign your message to Memo.text
Compute the linecount with caret.position as shown above
Resize the Memo height to your needs
Enable scrolling if necessary
make Memo visble

Winni

kupferstecher

  • Hero Member
  • *****
  • Posts: 583
Re: TMemo, count lines
« Reply #22 on: February 09, 2020, 11:36:04 am »
It finally works!

On Linux/Mac you might have better luck just trying DrawText (on a temporary canvas) and seeing what the drawn size is.
In your link there was a link to this topic:
https://forum.lazarus.freepascal.org/index.php/topic,21305.msg124432.html#msg124432

In the DrawText-options I needed to set DT_WORDBREAK, otherwise it wouldn't wordwrap a single line.

This is my code, I tested and it works under Windows, Linux/gtk2 and Linux/qt4.

Code: Pascal  [Select][+][-]
  1. function TEmbeddedModalFormManager.GetMemoHeight(AMemo: TMemo): Integer;
  2. var
  3.   aText: string;
  4.   vRect: TRect;
  5.   vFont: TFont;
  6. const
  7.   DrawTextFlags = DT_NOPREFIX or DT_EDITCONTROL or DT_CALCRECT or DT_WORDBREAK;
  8. begin
  9.   Result:= 1;
  10.   aText:= AMemo.Text;
  11.   if (aText = '') then EXIT;
  12.   if aMemo.Width < 10 then EXIT;
  13.  
  14.   vFont:= self.Canvas.Font;
  15.   self.Canvas.Font := AMemo.Font;
  16.   vRect:= Rect(0,0,AMemo.Width,self.Height);
  17.  
  18.   LCLIntf.DrawText(self.Canvas.Handle, PChar(aText), Length(aText),vRect, DrawTextFlags);
  19.  
  20.   self.Canvas.Font:= vFont;
  21.   Result:= vRect.Height;
  22.  
  23. end;

--
Before, I also tested winni's suggestion, under Windows it works.  (The caret.position is returning the line, not the pixel position, but the height can be calculated).
Under Linux/gtk2 a call to caret.position returns an error (missing handle), so it's not usable. (Should I file a bug report?)

rvk, winni: Thank You!

lazdeveloper

  • Jr. Member
  • **
  • Posts: 61
Re: TMemo, count lines
« Reply #23 on: April 14, 2020, 08:14:28 pm »
Hi all,
I have stuck in a same problem but for a different purpose.
I have two Memos say M1 and M2. The M1 will have the name and address as one line fed to it. while M2 will correspond the name in M1 with the price.
The width of M1 is more than M2 since M1 will have text while M2 just a number
I want to show the name in the first memo and the price in the second memo. If the text in the M1 is more than one lines I have to manually fill M2 with empty lines so that both memos can
Start new row equally.
Since M1 is wordwarpped I cannot know how many lines are shown there that have to be applied to M2
Unfortunately  (lines.count) is not the property that helps in this.
Any help?

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: TMemo, count lines
« Reply #24 on: April 14, 2020, 10:10:47 pm »
Hi!

Solution 1: Turn wordwrap of and activate the horizontal scrolling for the memos

Solution 2: Replace the Memos with Listboxes.

Winni

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: TMemo, count lines
« Reply #25 on: April 14, 2020, 10:18:13 pm »
Solution 3: Use a TStringGrid instead of memos; it's tailor-made for that kind of situations :)
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: TMemo, count lines
« Reply #26 on: April 14, 2020, 11:59:28 pm »
You can't do screen line counting with a Tmemo and get a reliable results , at least not in windows because windows does not really care what you are seeing on the screen, all it does is maintains accurate values for number of lines in a buffer..

  If you are in windows there are messages you can send to the memo to get all the info you need..
The only true wisdom is knowing you know nothing

lazdeveloper

  • Jr. Member
  • **
  • Posts: 61
Re: TMemo, count lines
« Reply #27 on: April 15, 2020, 12:50:17 am »
Many thanks for the replies.
I have to use memo since this is a report and the Memo is the report component.
The report is fortes CE report available via OPM.
I have like max of four different length text for M1 and corresponding number for M2 something like
MEMO1        | MEMO2|
name            |  number|
Tony Smith  |  233       |
and Jones   |                |
William.        |               |
Sara Anagn  |  444      |
Niven.           |               |

I can't use StringGrid since I am limited to the report component

Thanks

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: TMemo, count lines
« Reply #28 on: April 15, 2020, 01:40:10 am »
That's pretty cruddy looking   :o

 have you tried inserting tab character characters after each group ?

 That would be the value #9 in the text...

 For example:

    'A Word or Line'+#9+' |'+#9+'Another Word' etc...
The only true wisdom is knowing you know nothing

lazdeveloper

  • Jr. Member
  • **
  • Posts: 61
Re: TMemo, count lines
« Reply #29 on: April 15, 2020, 03:25:07 pm »
Oh no..
This is a quick way to show what I am doing in report
The "|" is just there to represent memo borders.
No special characters at all.
Consider yourself looking at two Memos next to each others.
I hope its clear now

 

TinyPortal © 2005-2018