Search code examples
delphidelphi-10.4-sydneytcolor

Add an included TColorListBox.Style color group at run-time without overwriting any existing custom colors?


I have a TColorListBox in a Delphi 10.4.2 32-bit VCL Application:

object ColorListBox1: TColorListBox
  Left = 0
  Top = 232
  Width = 498
  Height = 224
  Align = alBottom
  Selected = clScrollBar
  Style = [cbCustomColors]
  ItemHeight = 20
  TabOrder = 1
  ExplicitWidth = 484
end

I have added a few custom color items to the color list with the help of a TColorDialog:

procedure TForm1.btnAddClick(Sender: TObject);
begin
  if dlgColor1.Execute(Self.Handle) then
  begin
    // insert on top:
    ColorListBox1.Items.InsertObject(0, 'My Color', TObject(dlgColor1.Color));
  end;
end;

...with this result:

enter image description here

Now I try to add one of the included TColorListBox.Style color groups without overwriting the previously added custom colors:

procedure TForm1.btnAddGroupClick(Sender: TObject);
begin
  ColorListBox1.Style := ColorListBox1.Style + [cbStandardColors];
end;

But this OVERWRITES the previously added custom colors!

How can I add an included TColorListBox.Style color group like above at run-time without overwriting any existing custom colors?

(Please note that the "cbCustomColors" is included as default: Style = [cbCustomColors])


Solution

  • You have to save the existing colors in a temporary list:

    procedure TForm1.btnAddGroupClick(Sender: TObject);
    var
      CL: TStringList;
    begin
      CL := TStringList.Create;
      try
        CL.Assign(ColorListBox1.Items); // save existing colors in a temporary list
        ColorListBox1.Style := ColorListBox1.Style + [cbStandardColors];
        ColorListBox1.Items.AddStrings(CL); // now add the temporary list
      finally
        CL.Free;
      end;
    end;
    

    enter image description here

    If you want to keep the existing colors on top of the list you have to insert the temporary colors one by one:

    procedure TForm1.btnAddGroupClick(Sender: TObject);
    begin
      if not (cbStandardColors in ColorListBox1.Style) then
        AddColorGroup([cbStandardColors]);
    end;
    
    procedure TForm1.AddColorGroup(AColorGroup: TColorBoxStyle);
    var
      CL: TStringList;
      i: Integer;
    begin
      CL := TStringList.Create;
      try
        CL.Assign(ColorListBox1.Items); // save existing colors in a temporary list
        ColorListBox1.Items.BeginUpdate;
        try
          ColorListBox1.Style := ColorListBox1.Style + AColorGroup;
          // keep existing colors on top:
          for i := CL.Count - 1 downto 0 do // insert temporary colors back one by one
            ColorListBox1.Items.InsertObject(0, CL[i], CL.Objects[i]);
        finally
          ColorListBox1.Items.EndUpdate;
        end;
      finally
        CL.Free;
      end;
    end;