0

I have a TRichEdit with some RTF in it (text with formatting only) and I want to know if all the content of the TRichEdit is selected. To do so, I do:

var AllSelectd: Boolean;
//...
AllSelectd := MyRichEdit.SelLength = MyRichEdit.GetTextLen;

which works fine, except when the content has three lines or more. With zero to two lines, everything is fine. As soon as I reach three lines in my TRichEdit, the code above no longer works (MyRichEdit.SelLength < MyRichEdit.GetTextLen). Each line is terminated with CRLF (#13#10).

Is this a bug? How can I reliably check if everything is selected in the TRichEdit?

I use Delphi 10.4, if it changes anything.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AlexV
  • 22,658
  • 18
  • 85
  • 122
  • Moreover, if we have single line without carriage return, sellength is larger by 1. [Same issue](https://stackoverflow.com/questions/8725457/richedit-2-0s-usage-of-single-cr-character-as-linebreak-throws-off-selstart-cal) – MBo Sep 10 '21 at 04:28

1 Answers1

2

As mentioned in this topic, RichEdit 2.0 replaces CRLF pairs with CR internally, and retrieves LF's in some cases.

As workaround - calculate number of lines in selected range to make correction (SelText contains only CR's, GetTextLen works with text with retrieved CRLF, so counts both CR's and LF's). Remy Lebeau proposal is used.

var
  sel, getl, crcnt, i: integer;
  tx: string;
begin
  sel := RichEdit1.SelLength;
  getl := RichEdit1.GetTextLen;
  crcnt := SendMessage(Richedit1.Handle, EM_EXLINEFROMCHAR, 0, sel);
  Memo1.Lines.Add(Format('%d %d',[sel, getl - crcnt + 1]));
end;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
MBo
  • 77,366
  • 5
  • 53
  • 86
  • If you are going to retrieve the `SelText` anyway and grab its `Length()`, there is little point in retrieving the `SelLength` as well. On the other hand, have you considered using `EM_EXGETSEL` with `EM_EXLINEFROMCHAR` to calculate the number of lines in the selection without retrieving the actual text? – Remy Lebeau Sep 10 '21 at 15:57
  • @Remy Lebeau You are right. Seems that just using EM_EXLINEFROMCHAR with range 0..SelLength is enough – MBo Sep 10 '21 at 17:08
  • @Remy Lebeau I understand, but seems problem `all the text is selected` is solved with `0..SelLength` too – MBo Sep 10 '21 at 17:20
  • `EM_EXLINEFROMCHAR` returns a line index, but you are treating it as a character index, subtracting it from the text length. I assume you are doing that to subtract `LF`s from `CRLF` pairs, yes? The whole point of me suggesting `EM_EXLINEFROMCHAR` was to help *count lines* in the selection to offset the `SelText` length. Now I'm thinking this is not necessary at all, I would expect using `EM_EXGETSEL` by itself and then checking `rng.cpMin==0 && rng.cpMax==GetTextLen()` to work. – Remy Lebeau Sep 10 '21 at 17:20
  • @Remy Lebeau About charrange difference - no, error remains. For 5 one-symbol lines cpMin=0, cpMax=10, but GetTextLen is 13 – MBo Sep 10 '21 at 17:20
  • @Remy Lebeau Yes, I subtract line index (as carriage return count) from text length to compensate lack of LF's – MBo Sep 10 '21 at 17:26
  • MBo & @RemyLebeau clever solution, thanks! – AlexV Sep 10 '21 at 18:13