views:

1002

answers:

2

Hello!

I'm using the RoundRect GDI function to draw a rounded rectangle following this example: .NET CF Custom Control: RoundedGroupBox

Because all controls are square, it also draw the corners outside of the rounded rectangle. How can I make this space left outside the rectangle transparent?

The OnPaint method is:

protected override void OnPaint(PaintEventArgs e)
        {
            int outerBrushColor = HelperMethods.ColorToWin32(m_outerColor);
            int innerBrushColor = HelperMethods.ColorToWin32(this.BackColor);

            IntPtr hdc = e.Graphics.GetHdc();
            try
            {
                IntPtr hbrOuter = NativeMethods.CreateSolidBrush(outerBrushColor);
                IntPtr hOldBrush = NativeMethods.SelectObject(hdc, hbrOuter);
                NativeMethods.RoundRect(hdc, 0, 0, this.Width, this.Height, m_diametro, m_diametro);
                IntPtr hbrInner = NativeMethods.CreateSolidBrush(innerBrushColor);
                NativeMethods.SelectObject(hdc, hbrInner);
                NativeMethods.RoundRect(hdc, 0, 18, this.Width, this.Height, m_diametro, m_diametro);
                NativeMethods.SelectObject(hdc, hOldBrush);
                NativeMethods.DeleteObject(hbrOuter);
                NativeMethods.DeleteObject(hbrInner);
            }
            finally
            {
                e.Graphics.ReleaseHdc(hdc);
            }

            if (!string.IsNullOrEmpty(m_roundedGroupBoxText))
            {
                Font titleFont = new Font("Tahoma", 9.0F, FontStyle.Bold);
                Brush titleBrush = new SolidBrush(this.BackColor);
                try
                {
                    e.Graphics.DrawString(m_roundedGroupBoxText, titleFont, titleBrush, 14.0F, 2.0F);
                }
                finally
                {
                    titleFont.Dispose();
                    titleBrush.Dispose();
                }
            }

            base.OnPaint(e);
        }

An the OnPaintBackground is:

protected override void OnPaintBackground(PaintEventArgs e)
{
   if (this.Parent != null)
   {
        SolidBrush backBrush = new SolidBrush(this.Parent.BackColor);
        try
        {
            e.Graphics.FillRectangle(backBrush, 0, 0, this.Width, this.Height);
        }
        finally
        {
            backBrush.Dispose();
        }
    }
}

Thank you!

+1  A: 

When using standard managed operations, you need to make the "outer" color (that outside the rounded part) a specific color (magenta is a common one) then use SetColorKey to set that color as transparent.

This MSDN article has the basics on how you'd achieve it.

EDIT 1

Since you are P/Invoking your GDI operations, you could also continue with that. If you were drawing an image with transparency info, you could use alpha blending, but in this case you need to draw your entire "button" to a separate buffer and then P/Invoke MaskBlt to copy it to the Form's DC (which is what the CF is doing when you use colorkey transparency). Here's a desktop example, but the process is the same.

ctacke
This may not work for the poster because the control will still receive input from the transparent area. To avoid this, the CreateRectRgn (http://msdn.microsoft.com/en-us/library/ms908184.aspx) or ExtCreateRegion (http://msdn.microsoft.com/en-us/library/aa920742.aspx) functions must be used.
hjb417
It seems to me like the question is "how do I make the regoin transparent" not "how do I make the region not receive input". If it were the latter, CreateRectRegion isn't going to be much use for a CF developer anyway.
ctacke
I want to make the region transparent. The SetColorKey doesn't work because the use of e.Graphics.GetHdc(). I use it drawing images with transparency.
VansFannel
Why won't it work? You need to draw all of this to an offscreen buffer (which you should be doing anyway). Then when you copy it to the Graphics object passed in to the OnPaint (via DrawImage) you then use the color key with the ImageAttributes. If you don't want to do this, you can always just continue with your P/Invokes, as outlined in the edited answer above.
ctacke
Ok, I'm going to try it. Thank you!
VansFannel
I've just added more details. I think I must delete OnPaintBackground implementation, isn't it?
VansFannel
A: 

Does it work now? If yes, can you post your code again?

husara
I'm working on it.
VansFannel