0

I'm currently working with a component called TdsTaskBar, which intends to work like the TaskBar in windows, which means all opened windows (but now inside my application) are listed as buttons on the bottom of my application-window. This buttons are TSpeedButtons. Now I've changed the icons of my own windows, this icons get always displayed via the glyph of the SpeedButtons. The problem is, that the transparency isn't working.

I'm aware of the Transparency Color defined by the lower left corner pixel, but that's not my problem. The problem is, that transparent areas of the Glyphs show "random" image artifacts instead of the button-background, when changing the active window and then hovering over the buttons. This changes the background to the icon of the now active window, but with some distortion.

First window opened Second window opened, hovered over the button

I have NO clue how this artifacts get there, but I'm sure that it doesn't come from the TdsTaskBar- / TdsTaskButton-Component, because I examined all the paint-relevant procedures.

Does someone have an idea how to solve this problem? I already thought about drawing the background myself, but therefore I'd need to know the actual button color(s) behind this Glyph, and that's another thing where I'm not sure about how to figure it out.


Here the code snippet for assigning the glyph, the drawing is handled by standard Vcl SpeedButton Code:

procedure TTaskBarButton.AssignGlyphIcon;
var
  GlyphIcon: TIcon;
  b: TBitmap;
begin
  if TForm(owner).Icon.Empty then
    GlyphIcon := Application.Icon
  else
    GlyphIcon := TForm(owner).Icon;

  b := TBitmap.create;
  try
    b.Width := GlyphIcon.Width;
    b.Height := GlyphIcon.Height;
    b.Canvas.Brush.Color := b.TransparentColor;    // This two lines were added by me
    b.Canvas.FillRect(b.ClipRect);         // so that the background of my "helper" bitmap is transparent, too
    b.Canvas.Draw(0,0, GlyphIcon);
    Glyph.Width := 16;
    Glyph.Height := 16;
    Glyph.Canvas.StretchDraw(Rect(0, 0, 16, 16), b);
  finally
    b.free;
  end;
end;
Florian Koch
  • 1,372
  • 1
  • 30
  • 49
  • Seems to be a defect in the component to me, ask the [designer](http://www.pretty-software.com/)? – whosrdaddy Apr 07 '14 at 14:09
  • I have the full sources of the component, and it isn't that much code, just one short Unit. The drawing of the Glyph is simple and straightforward, I'm really sure the error doesn't lie in there. I'll edit the question and add the code of the Glyph drawing. – Florian Koch Apr 07 '14 at 14:12
  • I cannot see where you clear the background of `Glyph`. I also don't really understand why you need `b`. Finally, it looks like you are using images with alpha transparency. If so, why use `TransparentColor`? – David Heffernan Apr 07 '14 at 14:20
  • @DavidHeffernan I can also do the same "clear" I do in my bitmap in the glyph, but this doesn't change the outcome... The bitmap is used in case the application Icon isn't 16x16 pixel, so I can use the stretchdraw. I didn't invent this code, but I also didn't cahnge it because it seemed legit to me. – Florian Koch Apr 07 '14 at 14:35
  • @SirRufo This is the better solution, you are right, but this doesn't change anything regarding the transparency – Florian Koch Apr 07 '14 at 14:35
  • I got it wrong, the main problem is as David said, the `Glyph` background is not erased and because of the transparency you will get these artifacts – Sir Rufo Apr 07 '14 at 14:37
  • But then how do i erase the Glyph background right? I did the same Fillrect(ClipRect)-thing but this didnt change anything in what I see... – Florian Koch Apr 07 '14 at 14:42
  • @DavidHeffernan just noticed I completly ignored the second part of your comment - What do you mean with "Why use Transparent Color"? I thought the BitMap drawing doesn't support the normal transparency of, lets say a png, via alpha channel? – Florian Koch Apr 07 '14 at 14:44
  • Windows bitmaps do support alpha. They are the native raster image format of the platform so it would be astounding if they did not. A typical .bmp file won't support alpha, but that's different. Surely your image has alpha? – David Heffernan Apr 07 '14 at 14:49
  • It's a .ico file designed by someone in my company, but I'd say yes because they are normally transparent, when I open them with image-viewers. So you mean I don't have to use the Bitmap.Transparent, ok. But when I turn this off explicitely or just ignore it and take the standard implementation of the TdsTaskBar, the background is always white... Do I have to enable some options to use Alpha-aware drawing? Edit: I can also simply Assign my GlyphIcon to the Glyph, but it's the same: though the icon is transparent in the corner of my window, it then has a white background – Florian Koch Apr 07 '14 at 14:57
  • I'm not sure about those questions. I'd help but there's no SSCCE. I'd have to frab around trying to make a repro with little confidence I had done it right. – David Heffernan Apr 07 '14 at 15:24
  • I'm not sure wether I'm able to provide an SSCCE, because I need at least a project which can show own MDI-Windows to use the TaskBar component, so even a sample project isn't really short – Florian Koch Apr 07 '14 at 15:53
  • You think that it's an interaction with all of that? Doesn't sound likely to me. I don't understand why people are so reluctant to make SSCCEs. – David Heffernan Apr 07 '14 at 19:24

2 Answers2

2

You have to erase the Glyph background.

Here is a sample code, that should do the job

procedure TTaskBarButton.AssignGlyphIcon;
var
  b: TBitmap;
  r: TRect;
begin
  b := TBitmap.create;
  try
    if TForm( Owner ).Icon.Empty then
      b.Assign( Application.Icon )
    else
      b.Assign( TForm(Owner).Icon );

    r := TRect.Create( 0, 0, 16, 16 );
    Glyph.Width := r.Width;
    Glyph.Height := r.Height;
    // clear the background
    Glyph.Canvas.Brush.Color := Glyph.TransparentColor;
    Glyph.Canvas.FillRect( r );
    // draw the icon
    Glyph.Canvas.StretchDraw( r, b );
  finally
    b.free;
  end;
end;
Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
0

Found the solution: The TdsTaskBar (it's a TCustomPanel) has DoubleBuffered default set to false. The buttons inherit this setting. Changing this to true solves the problem.

So its seems like DoubleBuffering influences the functionality of Transparency on Buttons.

Florian Koch
  • 1,372
  • 1
  • 30
  • 49