【问题标题】:How can I know if all the text is selected in a TRichEdit when the text has three or more lines?当文本有三行或更多行时,我如何知道是否在 TRichEdit 中选择了所有文本?
【发布时间】:2021-09-10 03:34:21
【问题描述】:

我有一个 TRichEdit,其中包含一些 RTF(仅带格式的文本),我想知道是否选择了 TRichEdit 的所有内容。为此,我这样做:

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

效果很好,除非内容包含三行或更多行。零到两行,一切都很好。一旦我在 TRichEdit 中达到三行,上面的代码就不再有效(MyRichEdit.SelLength < MyRichEdit.GetTextLen)。每行都以 CRLF (#13#10) 结束。

这是一个错误吗?如何可靠地检查是否在 TRichEdit 中选择了所有内容?

我使用 Delphi 10.4,如果它有任何改变的话。

【问题讨论】:

  • 此外,如果我们有单行没有回车,sellength 会大 1。Same issue

标签: delphi richedit delphi-10.4-sydney


【解决方案1】:

this topic 中所述,RichEdit 2.0 在内部将 CRLF 对替换为 CR,并在某些情况下检索 LF。

作为解决方法 - 计算所选范围内的行数以进行更正(SelText 仅包含 CR,GetTextLen 使用检索到的 CRLF 的文本,因此计算 CR 和 LF)。使用了 Remy Lebeau 提案。

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;

【讨论】:

  • 如果您无论如何要检索SelText 并获取它的Length(),那么检索SelLength 也没有什么意义。另一方面,您是否考虑过使用EM_EXGETSELEM_EXLINEFROMCHAR 在不检索实际文本的情况下计算所选内容的行数?
  • @Remy Lebeau 你是对的。似乎只使用范围为 0..SelLength 的 EM_EXLINEFROMCHAR 就足够了
  • @Remy Lebeau 我明白了,但似乎问题all the text is selected 也用0..SelLength 解决了
  • EM_EXLINEFROMCHAR 返回一个行索引,但您将其视为字符索引,从文本长度中减去它。我假设您这样做是为了从 CRLF 对中减去 LFs,是吗?我建议 EM_EXLINEFROMCHAR 的全部目的是帮助 count lines 在选择中抵消 SelText 长度。现在我认为这根本没有必要,我希望自己使用EM_EXGETSEL,然后检查rng.cpMin==0 && rng.cpMax==GetTextLen() 工作。
  • @Remy Lebeau 关于 charrange 差异 - 不,错误仍然存​​在。对于 5 个单符号行 cpMin=0, cpMax=10, 但 GetTextLen 为 13
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2022-11-23
  • 2011-06-27
  • 1970-01-01
  • 2017-12-06
  • 2021-07-01
相关资源
最近更新 更多