This is what I use for cross platform dark theme detection.
I'm comparing the colors clWindow and clWindowText, since these system colors change perfectly as it is, and they typically should contrast to keep things readable. So it doesn't use any system specific calls.
So far it has worked very reliable under macOS and Linux - please correct me if I'm wrong or if there is an even easier way to do this. 😊Â
Â
// t4a_IsThisDarkTheme: Detects if the Dark Theme (true) has been enabled or not (false)
function t4a_ThisIsDarkTheme:boolean;
begin
Result := t4a_ColorToGrayScale(clWindow) < t4a_ColorToGrayScale(clWindowText); // guess dark theme
end;
{ Convert a color to grayscale, observing perception }
function t4a_ColorToGrayScale(aColor:TColor):TColor;
var
GreyNumber:integer;
begin
Result:=ColorToRGB(aColor);
// Convert Color to Grayscale if not yet Grayscale
// Grayscale  = (0.3 * Red) + (0.59 * Green) + (0.11 * Blue)
// Alternative = (0.2126 * Red) + (0.7152 * Green) + (0.0722 * Blue)
if (Red(Result)<>Green(Result)) and (Red(Result)<>Blue(Result)) then
 begin
  GreyNumber:= ( ( MathRound(Red(Result)  * 0.3) +
           MathRound(Green(Result) * 0.59) +
           MathRound(Blue(Result) * 0.11) ) div 3);
  if GreyNumber<0 then
   GreyNumber:=0
  else if GreyNumber>255 then
   GreyNumber:=255;
   Result:=RGBToColor(GreyNumber,GreyNumber,GreyNumber);
 end;
end;
Â
And I place the detection in the Form.OnPaint event, since this seems to get fired each time a theme changes, so my applications can respond to a theme change.
Â
procedure TForm1.FormPaint(Sender: TObject);
begin
Label1.Caption := BoolToStr( t4a_ThisIsDarkTheme, 'Dark Theme', 'Light Theme' );
end;Â Â
Â