1

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?

Michael
  • 41,989
  • 11
  • 82
  • 128
Gabriel
  • 20,797
  • 27
  • 159
  • 293
  • Beware: You appear to be conflating the line-ending sequences with the *key* that generates them. `Enter` is a key. It's the same key whether the computer is running Windows, Unix, or anything else. `Enter` is not a character. Pressing it on Windows will cause most programs to insert two characters: a carriage return followed by a newline. Unix will tend to insert only the newline. The application is free to interpret the key differently, though. The application is also free to display the characters how it wants. – Rob Kennedy Oct 16 '14 at 21:46
  • @RobKennedy-You are right. I fixed the question title. – Gabriel Oct 17 '14 at 09:27

2 Answers2

4

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.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • A recent problem I have seen with Delphi XE7. WMSetText will break the 'Custom styles' meaning that styles won't be applied to the scroll bars. – Gabriel Feb 11 '15 at 20:05
0

Just set the Lines.LineBreak property to LF:

memo1.lines.LineBreak := #10;

The default is #13#10 in Windows.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Turbo J
  • 7,563
  • 1
  • 23
  • 43
  • @Altar I think you need to fix the question. As written, you appear to ask how to deal with UNIX linefeeds. Now you seem to be wanting to deal with Windows linefeeds. Can you expand on this in the question. – David Heffernan Oct 16 '14 at 18:27
  • @Turbo This does do what you expect it to do. It makes no difference to the behaviour when pasting text that has UNIX linefeeds – David Heffernan Oct 16 '14 at 18:40
  • @DavidHeffernan-You are right. I added this to my question: " I want to handle all possible text formating (Mac, Win, Unix)". I hope this clarifies it. – Gabriel Oct 16 '14 at 20:22