Saving TMemoLines to a Logfile
Some Discoveries About Linebreaks
Summary
A small sample program illustrating this is available for download or cloning at GitHub:
While attempting to save multiple groups of lines from a TMemo
component, each new group appended to a log file, I expected each new group of lines saved to begin on a new line. After all, TStrings
has a TrailingLineBreak
option that should ensure that each group of lines ends with an appropriate Linebreak
.
Instead, each new group of lines immediately followed the preceding group without any sort of delimiter, Linebreak
or otherwise.
A little examination revealed that the TrailingLinebreak
was not being inserted. I set out to discover why. (I was not successful in my search!)
What I Tried to Do
Sometimes during development I use a TMemo
to record events, either system generated or manually entered by me. Then, I'd like to save those memo lines to a logfile for future reference. I have a small component that does all of this and also has a display option that will display the current log file in a separate window.
What I wanted to do was:
- Assume we have a
TMemo
object available - Assume we have a full path and file name available to receive the
TMemoLines
content. - Assume we have a procedure that appends the
TMemoLines
to the end of the log file. TStrings
has aTrailingLineBreak
option that whenTrue
(the default) should ensure that each series of lines ends with a line break.- Because each series of lines should end with a line break, when multiple insertions of lines takes place, each new group of lines should begin at the left margin.
It looks something like this:
What Actually Happened
What actually happens is for multiple insertions of lines from the memo, the first line of insertions following the first begins immediately following the end of the first insertion, thus running the two lines together.
One way to avoid this is to ensure that lines in the memo always end with a trailing line break. This means that if you're entering lines manually, you must remember to insert the trailing line break yourself. This might be acceptable unless the lines you're saving are generated by software that doesn't include the trailing line break. Overall, this is not a completely reliable solution and one that seems kind of specious given the fact that TStrings
includes a property especially for that purpose.
Why It Happened
I wasn't able to actually pinpoint the reason by examining the Delphi VCL source code. It seems to be related to the fact that the TStrings
of the TMemo
are really TMemoLines
, descended from TStrings
and in the process the Text
property is overridden to a method that does not examine the TrailingLinebreak
option.
If somebody can figure out what happened to the Text
property, I'd be interested to hear the explanation.
My Workaround
My workaround is fairly simple.
- Set up a
TStringList
as a work area - Use
MyStringList.Assign(TMemo.Lines)
to place theTMemolines
in the workStringList
. - Continue from there using the work
StringList
, which results in theText
property honoring theTrailingLineBreak
option.
Conclusion
Still kind of aggravating, but the workaround is easy to accomplish and given the infrequent use of most log files doesn't result in a lot of unnecessary overhead.
And so, on to the next problem.