0

The VirtualStringTree header has a 'Background' property but setting it to a different color does not change the color. I suspect the tree is rendered using Windows themes.

How can I set the color?

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Steve F
  • 1,527
  • 1
  • 29
  • 55
  • That property is used for header background, not for plates. And you would have to turn off themes for the control (exclude `toThemeAware` from `TreeOptions.PaintOptions`). What you're asking for sounds more like a task for custom drawing. What exactly do you want to paint (an image would be ideal) ? – TLama Sep 04 '15 at 11:29
  • Switching off ThemeAware is not an option because its not flat anymore. I just need a darker shade of gray as the header background color... – Steve F Sep 04 '15 at 11:38
  • [Like this](http://i.imgur.com/xevOLcX.png) ? Note, that the background has no gradient on that picture. That gradient needs some extra work. – TLama Sep 04 '15 at 11:49
  • The whole background including the column headers is a single color. See the possibilities for db-grid header color customization in TSMDbGrid (by Mike Sholnik) for an example. – Steve F Sep 04 '15 at 14:17
  • I think the best way forward is to make a request to the author to implement this (currently maintained by JAM Software). – Steve F Sep 08 '15 at 14:09
  • It might be enough to move the drawing code into a sort of `DefaultDrawHeaderBackground` and `DefaultDrawHeaderPlate` methods. If you look closer to the code I've made, you'll see that if there would be such method, I could just call it and at the end call my `ColorBlend` procedure. – TLama Sep 08 '15 at 14:14

2 Answers2

3

You can use property THeader.Background but you'll have to exclude toThemeAware from TreeOptions.PaintOptions. That would turn off themes, as TLama already said in his comment above.


I recommend you to use the events OnAdvancedHeaderDraw and OnHeaderDrawQueryElements. hoOwnerDraw has to be included in Header.Options for them to take effect.

In OnHeaderDrawQueryElements you set Elements to (at least) [hpeBackground] and in OnAdvancedHeaderDraw you do the custom drawing.

See this example (source):

procedure TfrmMain.MyVSTHeaderDrawQueryElements(Sender: TVTHeader;
  var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements);
begin
  Elements := [hpeBackground];
end;

procedure TfrmMain.MyVSTAdvancedHeaderDraw(Sender: TVTHeader;
  var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements);
begin
  if hpeBackground in Elements then
  begin
    PaintInfo.TargetCanvas.Brush.Color := clFuchsia; // <-- your color here
    if Assigned(PaintInfo.Column) then
      DrawFrameControl(PaintInfo.TargetCanvas.Handle, PaintInfo.PaintRectangle, DFC_BUTTON, DFCS_FLAT or DFCS_ADJUSTRECT); // <-- I think, that this keeps the style of the header background, but I'm not sure about that
    PaintInfo.TargetCanvas.FillRect(PaintInfo.PaintRectangle);
  end;
end;
René Hoffmann
  • 2,766
  • 2
  • 20
  • 43
  • Better add `if not Assigned(PaintInfo.Column) then` statement to the query elements event. The `hpeBackground` element is used also for drawing plates. And in the drawing event just fill the rectangle. – TLama Sep 04 '15 at 11:58
  • @TLama What do you mean with "plates"? – René Hoffmann Sep 04 '15 at 11:59
  • Great answer! I'll accept it when the code is final. – Steve F Sep 04 '15 at 12:01
  • [This](http://i.imgur.com/TvrB4de.png). And do just [this](http://pastebin.com/nT9NiaLZ). That themed painting attempt is poor. – TLama Sep 04 '15 at 12:04
  • Maybe, OP should clarify what he meant with "background". I understood him as that he wants to color both, plates and unused background space. If I misunderstood him, then you are totally right. – René Hoffmann Sep 04 '15 at 12:12
  • I think that its well understood what 'header' means. The entire top row is considered a header. – Steve F Sep 04 '15 at 12:48
  • Sure, but header has parts. The base parts are plates and background. You've said me that you want to have different background. Now we are talking about background and plates as well ? I'm confused :( – TLama Sep 04 '15 at 12:53
  • Sorry for the confusion. I just want the ability to set the header background color (the whole background including column headers with one single color). I am used to the functionality available in TSMDBGrid (Mike Sholnik). – Steve F Sep 04 '15 at 12:58
  • 1
    [Nothing fancy](http://pastebin.com/59a7X4D1). Due to lack of missing default drawing method you need to *copy* (and maintain) the painting method from the source (the code is from VTV 6.1.0). All that just for calling one extra function (that blends the rectangle over the just painted element). – TLama Sep 04 '15 at 13:25
  • @TLama: Thanks for the effort put into this. It looks like I have to go this route. – Steve F Sep 04 '15 at 14:18
  • @TLama: Your code looks very long. I think that its best that the authors implement the requested feature into the component, that way it will be most optimum, rather than all this custom draw events (VirtualStringTree1AdvancedHeaderDraw). So I will skip this code for now and just use the normal / default color. – Steve F Sep 08 '15 at 14:21
0
procedure TfrmDepositDefrayalSingly.vstItemsManuallyHeaderDrawQueryElements(Sender: TVTHeader;
  var PaintInfo: THeaderPaintInfo; var Elements: THeaderPaintElements);
begin
  Elements := [hpeBackground];
end;


procedure TfrmDepositDefrayalSingly.vstItemsManuallyAdvancedHeaderDraw(Sender: TVTHeader;
  var PaintInfo: THeaderPaintInfo; const Elements: THeaderPaintElements);
begin
  if hpeBackground in Elements then
  begin
    PaintInfo.TargetCanvas.Brush.Color := cGlobalVar.BasicColor;
    PaintInfo.TargetCanvas.FillRect(PaintInfo.PaintRectangle);

    if Assigned(PaintInfo.Column) then
    begin
      PaintInfo.TargetCanvas.Brush.Color := clGray;
      PaintInfo.TargetCanvas.FrameRect(PaintInfo.PaintRectangle);
    end;
  end;
end;
Pooya
  • 6,083
  • 3
  • 23
  • 43
sthruska
  • 3
  • 1