Changing windows colors with Delphi?

Question

How can I change Windows default colors from my Delphi application?

Related Articles and Replies

Re: webmaster Guido:

In your Delphi program, you can get the color of a Windows interface display element with the WinAPI function GetSysColor, and you can set the colors of elements with SetSysColors.

GetSysColor(nIndex) returns the red, green, blue (RGB) color of a Windows display element. nIndex is a DWORD value, for which you can use a symbolic value, such as:

COLOR_ACTIVECAPTION = the caption (title bar) of the active window;
COLOR_INACTIVECAPTION = the caption of all the inactive windows;
COLOR_CAPTIONTEXT = the text of the active window caption.

If you look up GetSysColor in the WinAPI help, you'll see the nIndex for the other elements' color.

SetSysColors(cElements, lpaElements, lpaRgbValues) sets the colors of a group of display elements. The parameters are:

  • cElements: an integer, equal to the number of elements to change. For example, if you want to change the color of both the active and the inactive window captions, cElements must be 2.
  • lpaElements: the address of an array with nIndex values, that indicate which display-elements to change.
  • lpaRgbValues: the address of an array of the RGB values of the new colors that you want to assign. You can calculate the color values, or let the user pick colors from a color-dialog, or you can directly use Delphi's symbolic color-names such as clWhite, clBlue, and so on.

Let's look at an example. By clicking on Button1, you want to change the colors of 3 Windows elements: the title bar of the active and the inactive window(s) and the text of the title bar of the active window (note that this third one also will change the text color of some other elements, see the WinAPI help or just try it out). Button2 should reset the colors to what they were when your Delphi program started.

First, we declare some unit-wide stuff:

implementation

{$R *.DFM}

const
  NrOfElements = 3;
  aElements: array [0..NrOfElements - 1] of DWORD =
    (COLOR_ACTIVECAPTION, 
     COLOR_INACTIVECAPTION, 
     COLOR_CAPTIONTEXT);

var
  aOldColors: array [0..NrOfElements - 1] of TColor;

When the program starts, save the original colors in the array aOldColors:

procedure TForm1.FormCreate(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to NrOfElements - 1 do
    aOldColors[i] := GetSysColor(aElements[i]);
end;

This is for setting the new colors:

procedure TForm1.btnSetColorsClick(Sender: TObject);
var
  aNewColors: array [0..NrOfElements - 1] of TColor;
begin
  // Calculate colors, let user pick colors, 
  // or use Delphi's symbolic names
  aNewColors[0] := clBlue;
  aNewColors[1] := clGreen;
  aNewColors[2] := clYellow;
  SetSysColors(NrOfElements, aElements, aNewColors);
end;

This will reset the old colors:

procedure TForm1.btnResetColorsClick(Sender: TObject);
begin
  SetSysColors(NrOfColors, aElements, aOldColors);
end;

Note: if you stop the program before resetting Windows' colors, they will stay that way until you restart Windows or until you make changes with Windows' own utilities.