Recent

Author Topic: Here's how to show coloured text logs in a resizable, borderless window  (Read 507 times)

Pallzi

  • Newbie
  • Posts: 2
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! :P

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.pas

The 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:

Code: Pascal  [Select][+][-]
  1. var
  2.   Style: Longint;
  3. begin
  4.   Style := GetWindowLong(Handle, GWL_STYLE);
  5.   SetWindowLong(Handle, GWL_STYLE, Style and not WS_CAPTION);
  6.   ...
  7.  

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:

Code: Pascal  [Select][+][-]
  1.   TTraceKind = (
  2.       tkNormal,       // normal text
  3.       tkTrace,        // detailed trace
  4.       tkInfo,         // highlighted information
  5.       tkError         // error text
  6.       );
  7.  
  8.   TTraceControl = (
  9.       tcNone,         // no special control
  10.       tcIndent,       // increase indention after trace
  11.       tcUnIndent,     // decrease indention before trace
  12.       tcBeginUpdate,  // suppresses output until tcEndUpdate is issued
  13.       tcEndUpdate,    // reveals traces since tcBeginUpdate was issued
  14.       tcClear         // clear log
  15.       );
  16.  
  17.  

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:

Code: Pascal  [Select][+][-]
  1. uses
  2.   LazTrace;
  3. ...
  4.   Trace(tcBeginUpdate);
  5.   Trace('Log test starting', tkInfo, tcIndent);
  6.   try
  7.     Trace('First entry');
  8.     Trace('1 + 1 = 2', tkTrace);
  9.     Trace('2 + 2 = 4', tkTrace);
  10.     Trace('Second entry');
  11.     Trace('A + A != B', tkTrace);
  12.     Trace('B + B != C', tkTrace);
  13.   finally
  14.     Trace('And we''re done!', tkInfo, tcUnIndent);
  15.     Trace(tcEndUpdate)
  16.   end;
  17.  

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:

Code: Pascal  [Select][+][-]
  1.   frmTrace.Visible := True;
  2.   frmTrace.SetFocus;
  3.  

And that's it!

Best regards,
Pallzi

Boleeman

  • Hero Member
  • *****
  • Posts: 1118
Re: Here's how to show coloured text logs in a resizable, borderless window
« Reply #1 on: February 08, 2026, 03:52:59 am »
Hi Pallzi.

Welcome to the Lazarus forum.

I recently came across a nice code sample of a border-less, resizable and moveable form (move and drag near the top).

Thought I would share.


I also played around with Delphi, but I like using FREE Lazarus better (Delphi is too commercial).
Dumped Delphi for Lazarus.


Pallzi

  • Newbie
  • Posts: 2
Re: Here's how to show coloured text logs in a resizable, borderless window
« Reply #2 on: February 08, 2026, 11:19:27 am »
Thanks Boleeman!

This is a much better method!

I knew it was possible to use WM_NCHITTEST for dragging a form, but didn't think of using it for resizing as well!

I've updated my code to use this method instead.
I modified it slightly so that you could click on the close button (it's a TSpeedButton which doesn't have a wndproc like most controls, if I understand correctly).
Also included a project file to make it easier to run.

And yeah, I prefer Lazarus over Delphi for that exact reason ;)
I'm working on a personal project that I would like to release as an open source one day, and that simply wouldn't be realistic with the chains and shackles that come with Delphi's terms and licensing.

Coding in Lazarus is making me a happier person than I ever was coding in Delphi :))))

Thanks again.

 

TinyPortal © 2005-2018