Hello all
I'm a Delphi veteran who just recently got hooked into using Lazarus and I'm very happy and pleased with it!
I did have a couple of issues that people have asked about in this forum before and although I didn't find a Copy and Paste solution in the forum, I did get enough information so that I could come up with a solution of my own.
I wanted to share these results with everyone interested

This is my first post on this forum so I hope it finds you well - and if not then feel free to yell back!

I wanted to create a simple (but cool looking) form for logging purposes and wanted it to have the following capabilities:
- The text in the log should be coloured so that some text would easily stick out.
- The form should have no title bar and still be resizable/draggable.
This turned out to be a bit challenging and I'll explain why.
Attached is a working solution (single form unit) which is ready for use in any project.
It is not a serious logging facility as it lacks file support, time stamping etc. but it does solve these two points mentioned above rather cleanly and nicely I think.
The colouring was rather easy to do with TSynEdit and a custom highlighter. I did find an excellent tutorial to follow and only needed to slim it down a little as we're colouring whole lines at once (simpler than working with per token).
https://github.com/alrieckert/lazarus/blob/master/examples/SynEdit/NewHighlighterTutorial/simplehl.pasThe second part turned out to be more challenging!
Borderless forms can usually not be resized. There is a known way (discussed on the forum) to remove the title bar via win32 API so I tried that first.
For this I placed this code in the FormCreate event:
var
Style: Longint;
begin
Style := GetWindowLong(Handle, GWL_STYLE);
SetWindowLong(Handle, GWL_STYLE, Style and not WS_CAPTION);
...
This did "almost" work the way I expected and hoped for. The form was resizable and most of the title bar was gone, but there remained a band showing on top of the form, about 5 pixels high, painted in that awful gray color and since the rest of the form was darkly lit this was really an eye sore!
After some failed attempts I finally gave up on this method and decided on having the form borderless instead (BorderStyle = bsNone) and trying to resize it using different approach.
I did manage this using mouse events (OnMouseDown, OnMouseMove, OnMouseUp) by setting the form bounds on the fly (in OnMouseMove) and though it added quite some code, I think it was totally worth it!
So this is mostly an exercise in doing that.
I think this solution should work across all platforms, but it's only tested on Win 10.
The solution has a main entry "procedure Trace(const s: string)" that has several overloads to easily manage colouring and indenting of the log entries.
Besides the "s" parameter that contains the message to log, there are two types of parameters that can go with it, which I'll explain:
TTraceKind = (
tkNormal, // normal text
tkTrace, // detailed trace
tkInfo, // highlighted information
tkError // error text
);
TTraceControl = (
tcNone, // no special control
tcIndent, // increase indention after trace
tcUnIndent, // decrease indention before trace
tcBeginUpdate, // suppresses output until tcEndUpdate is issued
tcEndUpdate, // reveals traces since tcBeginUpdate was issued
tcClear // clear log
);
The TTraceKind tells the trace level, so that you can control the verbosity (debug level) being logged.
This also affects the colours being applied.
Then you have TTraceControl (could perhaps have been better named TTraceCommand?) which controls the line formatting, and optionally suppresses rendering to the TSynEdit control to allow for better speeds when running.
An example of use:
uses
LazTrace;
...
Trace(tcBeginUpdate);
Trace('Log test starting', tkInfo, tcIndent);
try
Trace('First entry');
Trace('1 + 1 = 2', tkTrace);
Trace('2 + 2 = 4', tkTrace);
Trace('Second entry');
Trace('A + A != B', tkTrace);
Trace('B + B != C', tkTrace);
finally
Trace('And we''re done!', tkInfo, tcUnIndent);
Trace(tcEndUpdate)
end;
This gives the following results
Log test starting
First entry
1 + 1 = 2
2 + 2 = 4
Second entry
A + A != B
B + B != C
And we're done!
The form is autocreated for me (Project Options...) but it stays hiddien (Visible = False) so you would perhaps have a button "Show Log" where you call these:
frmTrace.Visible := True;
frmTrace.SetFocus;
And that's it!
Best regards,
Pallzi