TMemo 无法正确处理 Unix 文本(LF 作为行结尾)

2023-12-04

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

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

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

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

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


您具体询问的是行结束序列,但我们可以轻松地将讨论范围扩大到一般控制编辑框的内容。

2001 年,Peter Below 写道一个只接受数字的编辑控件需要处理的所有事情的概述。这些技术至今仍然适用,至少对于 Windows 开发来说是这样。总结如下:

  • 覆盖KeyPress过滤掉不需要的按键。 (就您而言,您不需要这个,因为没有任何keys你想排除。)
  • 处理wm_Paste说明从剪贴板粘贴的文本的消息。
  • 处理wm_SetText消息说明以大多数其他传统方式设置的文本。 (这可以处理您列表中的大部分内容:LoadFromFile, Add, Append, Insert, Text := ....)
  • 处理em_ReplaceSel说明所选文本被覆盖的消息。

在下面的文章中,他只是拒绝任何不合格的输入。但这可能不是您想要的。相反,你会想要正常化输入,以便它使用统一的行结束序列。您不只是吞下上面列出的文本更改消息,而是需要处理输入,然后将其转发到普通处理程序。

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

For wm_SetText and em_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 there.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TMemo 无法正确处理 Unix 文本(LF 作为行结尾) 的相关文章

随机推荐