TMemo cannot handle Unix text (LF as line ending) correctly

左心房为你撑大大i 提交于 2019-12-30 11:56:06

问题


TMemo cannot handle Unix enters (LF) correctly. Two lines separated with a LF are shown and treated as one line. I want to handle all possible text formating (Mac, Win, Unix).

Obviously I could check the text and replace the LF with CRLF every time I:

  • load text form file
  • paste text
  • use the Add() function
  • use the Insert() function
  • use the Appen() function
  • change the content via Text property

But this won't be an elegant solution.

Lazarus solved this problem with the Lines.TextLineBreakStyle property. There is anything similar in Delphi XE?


回答1:


You're asking specifically about line-ending sequences, but we can easily broaden the discussion to controlling the contents of an edit box in general.

In 2001, Peter Below wrote an outline of all the things you need to handle for an edit control that accepts only numerals. The techniques are still applicable today, at least for Windows development. Here's a summary:

  • Override KeyPress to filter out unwanted keystrokes. (In your case, you don't need this because there aren't any keys you want to exclude.)
  • Handle the wm_Paste message to account for text pasted from the clipboard.
  • Handle the wm_SetText message to account for text being set in most other conventional ways. (This takes care of most of your list: LoadFromFile, Add, Append, Insert, Text := ....)
  • Handle the em_ReplaceSel message to account for selected text being overwritten.

In Below's write-up, he simply rejects any non-conforming input. That's probably not what you want, though. Instead, you'll want to normalize the input so that it uses uniform line-ending sequences. Rather than just swallow the text-changing messages listed above, you'll want to massage the input and then forward it to the normal handler.

For controlling line endings, Delphi already provides a function that does the kind of massaging you want: AdjustLineBreaks. You can pick whether you want Unix- or Windows-style line endings. (Note that not even Macintosh uses Mac-style line endings anymore.) You probably want tlbsCRLF because that's the style the Windows edit control knows how to display; as you've noted, it doesn't display line breaks if there aren't any carriage returns.

For wm_SetText and em_ReplaceSel, the change is easy. Here's a sketch:

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

It's not quite so obvious for wm_Paste because you're not given the new text, and you're not supposed to change the text that's currently on the clipboard. Instead, you can opt not to call inherited, handling the effects of pasting yourself. Something like this:

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;

Since assigning SelText goes through the em_ReplaceSel message, you might not even need to call AdjustLineBreaks there.




回答2:


Just set the Lines.LineBreak property to LF:

memo1.lines.LineBreak := #10;

The default is #13#10 in Windows.



来源:https://stackoverflow.com/questions/26405800/tmemo-cannot-handle-unix-text-lf-as-line-ending-correctly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!