CodeRage 2019 – VCL – The DARK side

As in all things there are fashions in UI and UX design. Right now perhaps the biggest trend is “dark mode”. Unless you’ve been living under a rock you probably know this is where the operating system – Windows, iOS, macOS and Android – supports a user interface theme where the elements can be set to a “dark mode” which generally means all those big swathes of white automagically turn to a dark charcoal or black color.

Windows 10 supports such a mode. If you’re running one of the later builds you’ll find that all sorts of things can be ‘dark’.

Here’s Windows Explorer running in Dark Mode on Windows 10

I personally run all my devices – I use Windows, macOS, iOS and Android every day – in dark mode. I suffer from a harmless but annoying visual issue which people commonly call “floaters”. It’s a factor of my age and eyesight. This means that bright white screens are not optimal since these little whispy things float around in my field of view while I am trying to get on with the job of coding. With Dark Mode enabled the floaters, which are also dark, are almost completely mitigated to the point where I don’t even notice them.

So, for me, and perhaps others, Dark Mode is a huge benefit rather than just an aesthetic choice and I want every app I can to support it.

This is where my CodeRage 2019 video (below) comes in. We can detect whether Windows 10 is running in Dark or regular ‘light’ mode using standard and fairly straight-forward Delphi code. When we know what mode the OS is running in we can use the power of Delphi’s VCL to swap the entire visual experience of our application to an appropriate theme.

In the video I show you how to do this with a simple Delphi unit I wrote which you can include in your own apps. There’s also a demo project you can play with.

One thing I don’t discuss is what to do if your app is already running and then the user changes the Windows theme from light to dark or vice versa.

To cope with that scenario you need to trap the WM_SYSCOLORCHANGE Windows message.

procedure WMSysColorChange(var Message: TWMSysColorChange); message WM_SYSCOLORCHANGE;

When the WM_SYSCOLORCHANGE message is triggered you then need to check the Windows theme mode and react accordingly. Like so:

SetAppropriateThemeMode('Carbon', 'Windows10');

Note that all of this pertains to Microsoft Windows – and Windows 10 onwards. Other OS do it differently. Note also that Delphi 10.3.3 Rio has just been released and this includes specific code for Dark mode in your apps.

Linkage

The link to the full video is here:

The code samples can be found on my GitHub pages: https://github.com/checkdigits/delphidarkmode

4 thoughts on “CodeRage 2019 – VCL – The DARK side

  1. Hi, Ian! I’ve got one question. How do I apply this theme to the buttons, grids, etc? I managed to do as you said, except that the modifications were not applied to these components.

    1. Note that I have also replied to your comment on the YouTube video.

      Hi Alexandre – how you apply the style depends on whether or not the component is one which ‘understands’ styles and if it is FMX or VCL.

      In most cases if you include the correct unit in your uses clause you can then call the TStyleManager to get the actual values for system colors and then use them to apply colors to the appropriate properties of any component which doesn’t support styles. If the component does support styles then you can create custom style elements and apply that element to the control.

      To do things manually – If you are using VCL then in your uses clause make sure you have Vcl.Themes – for FireMonkey FMX make sure to include FMX.Styles instead (it is probably there already).

      Now, somewhere in your formcreate code or similar have a routine like this:

      AColor: TColor; // For VCL

      or

      AColor: TAlphaColor; // for FMX

      Now you can do this:

      AColor := TStyleManager.ActiveStyle.GetSystemColor(clBtnFace);

      or

      AColor := := TStyleManager.ActiveStyle.GetSystemColor(clHighlight);

      etc etc – for any of the system colors.

      Then you can use the AColor variable to assign a value to any of the component’s colors>

      You can see an example of this in the VCL – if you open VCL.Grids and navigate to the DrawCellBackground method you will see how they obtain and use the correct system colors, adjusted for the style.

      There are lots of other ways to do this – the use of Styles is a big subject – a Google search will reveal a few answers. Good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *