1

TMemo 无法正确处理 Unix 输入 (LF)。显示用 LF 分隔的两条线并将其视​​为一条线。我想处理所有可能的文本格式(Mac、Win、Unix)。

显然,我每次都可以检查文本并用 CRLF 替换 LF:

  • 加载文本表单文件
  • 粘贴文本
  • 使用 Add() 函数
  • 使用 Insert() 函数
  • 使用 Appen() 函数
  • 通过 Text 属性更改内容

但这不会是一个优雅的解决方案。

Lazarus 使用 Lines.TextLineBreakStyle 属性解决了这个问题。Delphi XE中有类似的东西吗?

4

2 回答 2

4

您是在专门询问行尾序列,但我们可以轻松地将讨论范围扩大到控制编辑框的内容。

在 2001 年,Peter Above 写了一个大纲,概述了您需要为只接受数字的编辑控件处理的所有事情。这些技术在今天仍然适用,至少对于 Windows 开发。这是一个摘要:

  • 覆盖KeyPress以过滤掉不需要的击键。(在您的情况下,您不需要这个,因为您没有要排除的任何键。)
  • 处理wm_Paste消息以说明从剪贴板粘贴的文本。
  • 处理wm_SetText消息以说明以大多数其他常规方式设置的文本。(这会处理您的大部分列表:LoadFromFile, Add, Append, Insert, Text := ...。)
  • 处理em_ReplaceSel消息以说明被覆盖的选定文本。

在下面的文章中,他简单地拒绝了任何不合格的输入。不过,这可能不是您想要的。相反,您需要对输入进行规范化,以便它使用统一的行尾序列。而不是仅仅吞下上面列出的文本更改消息,您需要按摩输入,然后将其转发给普通处理程序。

为了控制行尾,Delphi 已经提供了一个函数来做你想要的那种按摩:AdjustLineBreaks. 您可以选择是否需要 Unix 或 Windows 样式的行尾。(请注意,甚至 Macintosh 也不再使用 Mac 样式的行尾。)您可能想要tlbsCRLF,因为这是 Windows 编辑控件知道如何显示的样式;正如您所指出的,如果没有任何回车,它不会显示换行符。

对于wm_SetTextem_ReplaceSel,改变很容易。这是一个草图:

procedure TLineNormalizingMemo.WMSetText(var Message: TWMSetText);
var
  s: string;
begin
  s := Message.Text;
  s := AdjustLineBreaks(s);
  Message.Text := PChar(s);
  inherited;
end;

这不是很明显,wm_Paste因为您没有获得新文本,并且您不应该更改剪贴板上当前的文本。相反,您可以选择不调用inherited,处理粘贴自己的效果。像这样的东西:

procedure TLineNormalizingMemo.WMPaste(var Message: TWMPaste);
var
  s: string;
begin
  if Clipboard.HasFormat(cf_Text) then begin
    s := Clipboard.AsText;
    s := AdjustLineBreaks(s);
    SelText := s;
  end;
end;

由于分配SelText是通过em_ReplaceSel消息进行的,因此您甚至可能不需要打电话给AdjustLineBreaks那里。

于 2014-10-16T21:42:32.530 回答
0

只需将Lines.LineBreak属性设置为LF

memo1.lines.LineBreak := #10;

默认设置#13#10在 Windows 中。

于 2014-10-16T13:46:29.510 回答