when overriding the button control you must also set ControlStyles.Opaque to
false.
\\\
SetStyle(ControlStyles.AllPaintingInWmPaint
| ControlStyles.DoubleBuffer
| ControlStyles.UserPaint
| ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.Opaque, false);
this.BackColor = Color.Transparent;
///
I sincerely thank everyone for taking the time to look at this.
I added Opaque as you suggested, and _still_ get black backgrounds. I
also added the DoubleBuffer style as you suggested, although I had not
originally planned to double buffer the drawing. Either way, black
backgrounds around the buttons.
I'm going to go for broke and post all of the button subclass code.
To test this, create a form, give it a background image, create a button
on the form, then change the declaration and creation of the Button to
FancyButton. To see what the button should look like (i.e. without
black background), uncomment the code segment starting with "if
(Parent.BackgroundImage == null)". But the performance will be terrible
if you do that.
Thank you for your assistance,
Tim Crews
GECO, Inc.
####################################################
public class FancyButton : Button
{
private int PenWidth;
private int ShadowHeight;
private int ButtonThickness;
private bool ButtonPressed;
public FancyButton() : base()
{
PenWidth = 1;
ButtonPressed = false;
// All of the following added per suggestions of newsgroup
// respondents.
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.Opaque, true);
this.BackColor = Color.FromArgb(0,this.BackColor);
}
public void SpecialRoundRect (Rectangle rect,
Color BaselineColor,
System.Windows.Forms.PaintEventArgs e,
bool Shade3D,
bool LoOutline,
bool HiOutline)
{
rect.Inflate(-1*PenWidth,-1*PenWidth);
int CurveSize = Math.Min(rect.Width, rect.Height) / 2;
int CurveHalfSize = CurveSize/2;
int CurveHalfLeft = rect.Left + CurveHalfSize;
int CurveHalfRight = rect.Right-CurveHalfSize;
int CurveHalfTop = rect.Top + CurveHalfSize;
int CurveHalfBottom = rect.Bottom-CurveHalfSize;
Rectangle TopLeft = new Rectangle
(rect.Left,rect.Top,CurveSize,CurveSize);
Rectangle TopRight = new Rectangle
(rect.Right-CurveSize,rect.Top,CurveSize,CurveSize);
Rectangle BottomLeft = new Rectangle
(rect.Left,rect.Bottom-CurveSize,CurveSize,CurveSize);
Rectangle BottomRight = new Rectangle
(rect.Right-CurveSize,
rect.Bottom-CurveSize,
CurveSize,CurveSize);
int MiddleX = (rect.Right + rect.Left) / 2;
int MiddleY = (rect.Top + rect.Bottom) / 2;
SolidBrush BaselineBrush, LoBrush, MedBrush, HiBrush;
Pen BaselinePen, LoPen, MedPen, HiPen;
BaselineBrush = new SolidBrush(BaselineColor);
BaselinePen = new Pen(BaselineBrush, PenWidth);
if (Shade3D)
{
// The low color should be a lot darker version of the
// specified BaselineColor
byte ShadowR, ShadowG, ShadowB;
ShadowR = (byte)((int)BaselineColor.R*2/3);
ShadowG = (byte)((int)BaselineColor.G*2/3);
ShadowB = (byte)((int)BaselineColor.B*2/3);
Color ShadowColor = Color.FromArgb
(ShadowR, ShadowG, ShadowB);
LoBrush = new SolidBrush(ShadowColor);
LoPen = new Pen(LoBrush, PenWidth);
// The medium color should be a somewhat darker version of
// the specified BaselineColor
byte MediumR, MediumG, MediumB;
MediumR = (byte)((int)BaselineColor.R*4/5);
MediumG = (byte)((int)BaselineColor.G*4/5);
MediumB = (byte)((int)BaselineColor.B*4/5);
Color MediumColor = Color.FromArgb
(MediumR, MediumG, MediumB);
MedBrush = new SolidBrush(MediumColor);
MedPen = new Pen(MedBrush, PenWidth);
// The high color should be a brighter version of the button
// BaselineColor
byte HighlightR, HighlightG, HighlightB;
HighlightR = (byte)(
(int)BaselineColor.R
+ (
(255-BaselineColor.R)
*1/3
)
);
HighlightG = (byte)(
(int)BaselineColor.G
+ (
(255-BaselineColor.G)
*1/3
)
);
HighlightB = (byte)(
(int)BaselineColor.B
+ (
(255-BaselineColor.B)
*1/3
)
);
Color HighlightColor = Color.FromArgb
(HighlightR, HighlightG, HighlightB);
HiBrush = new SolidBrush(HighlightColor);
HiPen = new Pen(HiBrush, PenWidth);
}
else
{
LoBrush = BaselineBrush;
LoPen = BaselinePen;
MedBrush = BaselineBrush;
MedPen = BaselinePen;
HiBrush = BaselineBrush;
HiPen = BaselinePen;
}
Pen OutlinePen;
if (LoOutline)
OutlinePen = new Pen(Color.Black,PenWidth);
else if (HiOutline)
OutlinePen = new Pen(Color.White,PenWidth);
else
OutlinePen = new Pen (Color.Black,PenWidth);
// unused, but prevents compiler warning
if (Shade3D)
{
GraphicsPath PathUpperLeft = new GraphicsPath();
PathUpperLeft.StartFigure();
PathUpperLeft.AddArc(TopLeft,180,90);
PathUpperLeft.AddLine
(CurveHalfLeft,rect.Top,MiddleX,MiddleY);
PathUpperLeft.CloseFigure();
e.Graphics.FillPath(HiBrush,PathUpperLeft);
e.Graphics.DrawPath(MedPen,PathUpperLeft);
GraphicsPath PathUpper = new GraphicsPath();
PathUpper.StartFigure();
PathUpper.AddLine
(CurveHalfLeft,rect.Top,CurveHalfRight,rect.Top);
PathUpper.AddLine(CurveHalfRight,rect.Top,MiddleX,MiddleY);
PathUpper.CloseFigure();
e.Graphics.FillPath(HiBrush,PathUpper);
e.Graphics.DrawPath(MedPen,PathUpper);
GraphicsPath PathUpperRight = new GraphicsPath();
PathUpperRight.StartFigure();
PathUpperRight.AddArc(TopRight,270,90);
PathUpperRight.AddLine
(rect.Right,CurveHalfTop,MiddleX,MiddleY);
PathUpperRight.CloseFigure();
e.Graphics.FillPath(MedBrush,PathUpperRight);
e.Graphics.DrawPath(MedPen,PathUpperRight);
GraphicsPath PathRight = new GraphicsPath();
PathRight.StartFigure();
PathRight.AddLine
(rect.Right,CurveHalfTop,rect.Right,CurveHalfBottom);
PathRight.AddLine
(rect.Right,CurveHalfBottom,MiddleX,MiddleY);
PathRight.CloseFigure();
e.Graphics.FillPath(LoBrush,PathRight);
e.Graphics.DrawPath(MedPen,PathRight);
GraphicsPath PathLowerRight = new GraphicsPath();
PathLowerRight.StartFigure();
PathLowerRight.AddArc(BottomRight,0,90);
PathLowerRight.AddLine
(CurveHalfRight,rect.Bottom,MiddleX,MiddleY);
PathLowerRight.CloseFigure();
e.Graphics.FillPath(LoBrush,PathLowerRight);
e.Graphics.DrawPath(MedPen,PathLowerRight);
GraphicsPath PathLower = new GraphicsPath();
PathLower.StartFigure();
PathLower.AddLine
(CurveHalfRight,rect.Bottom,CurveHalfLeft,rect.Bottom);
PathLower.AddLine
(CurveHalfLeft,rect.Bottom,MiddleX,MiddleY);
PathLower.CloseFigure();
e.Graphics.FillPath(LoBrush,PathLower);
e.Graphics.DrawPath(MedPen,PathLower);
GraphicsPath PathLowerLeft = new GraphicsPath();
PathLower.StartFigure();
PathLowerLeft.AddArc (BottomLeft,90,90);
PathLowerLeft.AddLine
(rect.Left,CurveHalfBottom,MiddleX,MiddleY);
PathLowerLeft.CloseFigure();
e.Graphics.FillPath(MedBrush,PathLowerLeft);
e.Graphics.DrawPath(MedPen,PathLowerLeft);
GraphicsPath PathLeft = new GraphicsPath();
PathLeft.StartFigure();
PathLeft.AddLine
(rect.Left,CurveHalfBottom,rect.Left,CurveHalfTop);
PathLeft.AddLine(rect.Left,CurveHalfTop,MiddleX,MiddleY);
PathLeft.CloseFigure();
e.Graphics.FillPath(HiBrush,PathLeft);
e.Graphics.DrawPath(MedPen,PathLeft);
}
GraphicsPath PathWhole = new GraphicsPath();
PathWhole.StartFigure();
PathWhole.AddArc(TopLeft,180,90);
PathWhole.AddArc(TopRight,270,90);
PathWhole.AddArc(BottomRight,0,90);
PathWhole.AddArc(BottomLeft,90,90);
PathWhole.CloseFigure();
if (!Shade3D)
{
e.Graphics.FillPath(BaselineBrush,PathWhole);
}
if (LoOutline || HiOutline)
{
e.Graphics.DrawPath(OutlinePen,PathWhole);
}
}
protected override void OnPaint (PaintEventArgs e)
{
if ((Width>50) && (Height>50))
{
ShadowHeight=10;
ButtonThickness=20;
}
else
{
ShadowHeight = 3;
ButtonThickness = 7;
}
Rectangle ButtonRectangle = new Rectangle(0,0,Width,Height);
// Start by filling in the background image of the parent form.
// This is necessary so that the parts of the bounding rectangle
// that are not actually occupied by any part of the button will
// look like they show the form's background.
// if (Parent.BackgroundImage == null)
// {
// SolidBrush SolBrush = new SolidBrush
// (Parent.BackColor);
// e.Graphics.FillRectangle (SolBrush,ButtonRectangle);
// }
// else
// {
// // Note: "Bounds" coordinates are relative to parent
// // form, while ButtonRectangle coordinates are
// // relative to the button.
// TextureBrush TexBrush = new TextureBrush
// (Parent.BackgroundImage, Bounds);
// e.Graphics.FillRectangle (TexBrush,ButtonRectangle);
// }
ButtonRectangle.Inflate
(-1*(ShadowHeight/2),-1*(ShadowHeight/2));
// Move the button if it is pressed
if (ButtonPressed)
{
ButtonRectangle.Offset(ShadowHeight/3,ShadowHeight/3);
}
else
{
ButtonRectangle.Offset
(-1*(ShadowHeight/2),-1*(ShadowHeight/2));
}
// Draw button shadow
Rectangle ShadowRectangle = e.ClipRectangle;
ShadowRectangle.Inflate
(-1*(ShadowHeight/2),-1*(ShadowHeight/2));
ShadowRectangle.Offset(ShadowHeight/2,ShadowHeight/2);
SpecialRoundRect
(ShadowRectangle,Color.Black,e,false,false,false);
// Draw button edges
SpecialRoundRect
(ButtonRectangle,this.BackColor,e,true,true,false);
// Draw button face
ButtonRectangle.Inflate
(-1*(ButtonThickness/2),-1*(ButtonThickness/2));
SpecialRoundRect
(ButtonRectangle,this.BackColor,e,false,false,true);
// Draw the button text in the specified font and color
if (this.Text.Length > 0)
{
StringFormat textFormat = new StringFormat();
textFormat.Alignment = StringAlignment.Center;
textFormat.LineAlignment = StringAlignment.Center;
e.Graphics.DrawString(this.Text, this.Font,
new SolidBrush(this.ForeColor),
ButtonRectangle, textFormat);
}
}
protected override void OnMouseDown
(System.Windows.Forms.MouseEventArgs e )
{
ButtonPressed = true;
this.Invalidate();
this.OnClick(e);
}
protected override void OnMouseUp
(System.Windows.Forms.MouseEventArgs e)
{
ButtonPressed = false;
this.Invalidate();
}
protected override void OnClick(System.EventArgs e)
{
base.OnClick(e);
}
}