Windows Develop Bookmark and Share   
 index > Windows Forms General > How to create a alpha-blended & transparent rectangle with shadow
 

How to create a alpha-blended & transparent rectangle with shadow

How to draw a round-edge rectangle (lenght 200, height 30). Border color should be white and the interior totally tansparent? Plus the borders should be alpha-blended with smooth shadows / blurring effect? Is it possible to create this using .NET's native GDI+?
re infecta  Friday, September 08, 2006 3:19 PM

The following piece of code will get you a rounded rectangle with a alpha blended white border:

protected override void OnPaint(PaintEventArgs e)

{

Rectangle b = new Rectangle(30, 30, 200, 30);

using (GraphicsPath path = new GraphicsPath(FillMode.Alternate))

{

path.AddArc(b.X, b.Y, 10, 10, 180, 90);

path.AddLine(b.X + 5, b.Y, b.X + b.Width - 5, b.Y);

path.AddArc(b.X + b.Width - 10, b.Y, 10, 10, 270, 90);

path.AddLine(b.X + b.Width, b.Y + 5, b.X + b.Width, b.Y + b.Height - 5);

path.AddArc(b.X + b.Width - 10, b.Y + b.Height - 10, 10, 10, 0, 90);

path.AddLine(b.X + b.Width - 5, b.Y + b.Height, b.X + 5, b.Y + b.Height);

path.AddArc(b.X, b.Y + b.Height - 10, 10, 10, 90, 90);

path.CloseFigure();

using (Pen pen = new Pen(Color.FromArgb(64, 255, 255, 255), 3.0f))

{

e.Graphics.DrawPath(pen, path);

}

}

}

I'm not sure what do you mean by "shadow" as for "blurring" that's not something you can achieve easily using GDI++.

Mike Danes  Saturday, September 09, 2006 9:39 PM
Thank you!

Okay the shadow can be a tricky one, so I tried to approach this problem my using a transparent png file that represents the glass-like bar.

Look at this example I made: example.gif.

First there is the image in image editor (where you can see the complete transparency). The second is the goal I want to achieve: a form that is completely transparent so that the shadow of the bar looks smooth. The last image at the bottom is the current state (the problem). The image is in a picturebox that has the same background color as the form (white). White is set at the transparency key in order to make the form transparent. Opacity is 100 %.

I think the problem is that the form is transparent only for one color (white) but the shadow has multiple shades of gray. How to achieve the goal and make the shadow look better?

I would appreciate any help! I'm using VB.net.


re infecta  Sunday, September 10, 2006 9:46 AM

Yes, the problem is that the transparecy color is only one. You need per pixel alpha to achive what you want. See this Code Project page for a sample:

http://www.thecodeproject.com/cs/media/perpxalpha_sharp.asp

It's C#. If needed I can translate it to VB.NET.

Now I'm not sure what you're trying to do. If you're trying to do a Window Vista style window that has a glass border then you're pretty much out of luck. TransparencyKey can be used to make a non rectangular form, but not transparent regions. Opacity can be used to make the whole form transparent, but you need only the borders to be transparent. Per pixel alpha would work, but per pixel alpha forms don't display their child controls so they're sort of useless.

Mike Danes  Sunday, September 10, 2006 11:44 AM
That article looks interesting and could work. I would be most grateful if you had time to translate that to VB.NET! I would like to set the png image as form's background in order to be able to put a textbox on it.
re infecta  Sunday, September 10, 2006 1:06 PM
But I told you... any form child controls (including the TextBox) won't be visible.
Mike Danes  Sunday, September 10, 2006 1:56 PM
I'm sorry, I didn't understand the concept "child control". So there is no solution around this problem?
re infecta  Sunday, September 10, 2006 2:17 PM
make the forms background color consistent, and then use that color as the background for the shadow in your image editor.
Chris Rush  Sunday, September 10, 2006 4:38 PM

Here's the translated version of the PerPixelAlphaForm. To use it call the SetBitmap function with your transparent image.

But as I already told you child controls won't be visibile so I don't know what good is it. The only thing that comes to my mind to make this work would be to show another form (that contains the textbox) on top of transparent form and try to move/resize/close those two forms together. That's not going to be very easy, if it works at all. On top of this all you should not expect to get very good performance if the form is large.

I hope I understood your problem correctly ...

Imports System.Drawing.Imaging

Imports System.Runtime.InteropServices

Public Class PerPixelAlphaForm

Inherits Form

Private Declare Auto Function GetDC Lib "user32.dll" (ByVal hWnd As IntPtr) As IntPtr

Private Declare Auto Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hDC As IntPtr) As IntPtr

Private Declare Auto Function SelectObject Lib "gdi32.dll" (ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr

Private Declare Auto Function UpdateLayeredWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal hdcDst As IntPtr, ByRef pptDst As WIN32POINT, ByRef psize As WIN32SIZE, ByVal hdcSrc As IntPtr, ByRef pptSrc As WIN32POINT, ByVal crKey As Integer, ByRef pblen As BLENDFUNCTION, ByVal dwFlags As Integer) As Integer

Private Declare Auto Function ReleaseDC Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer

Private Declare Auto Function DeleteObject Lib "gdi32.dll" (ByVal hObject As IntPtr) As Boolean

Private Declare Auto Function DeleteDC Lib "gdi32.dll" (ByVal hDC As IntPtr) As Boolean

<StructLayout(LayoutKind.Sequential)> _

Private Structure WIN32POINT

Public x As Integer

Public y As Integer

Public Sub New(ByVal x As Integer, ByVal y As Integer)

Me.x = x

Me.y = y

End Sub

End Structure

<StructLayout(LayoutKind.Sequential)> _

Private Structure WIN32SIZE

Public cx As Integer

Public cy As Integer

Public Sub New(ByVal cx As Integer, ByVal cy As Integer)

Me.cx = cx

Me.cy = cy

End Sub

End Structure

<StructLayout(LayoutKind.Sequential, Pack:=1)> _

Private Structure BLENDFUNCTION

Public BlendOp As Byte

Public BlendFlags As Byte

Public SourceConstantAlpha As Byte

Public AlphaFormat As Byte

End Structure

Public Sub SetBitmap(ByVal bitmap As Bitmap, ByVal opacity As Byte)

If (bitmap.PixelFormat <> PixelFormat.Format32bppArgb) Then

Throw New ArgumentException("The bitmap must be 32ppp with alpha-channel.", "bitmap")

End If

Dim hDCScreen As IntPtr = GetDC(IntPtr.Zero)

Dim hDCMemory As IntPtr = CreateCompatibleDC(hDCScreen)

Dim hBitmap As IntPtr = IntPtr.Zero

Dim hOldBitmap As IntPtr = IntPtr.Zero

Try

hBitmap = bitmap.GetHbitmap(Color.FromArgb(0))

hOldBitmap = SelectObject(hDCMemory, hBitmap)

Dim size As New WIN32SIZE(bitmap.Width, bitmap.Height)

Dim pointSource As New WIN32POINT(0, 0)

Dim topPos As New WIN32POINT(Left, Top)

Dim blend As BLENDFUNCTION = New BLENDFUNCTION

blend.BlendOp = 0

blend.BlendFlags = 0

blend.SourceConstantAlpha = opacity

blend.AlphaFormat = 1

UpdateLayeredWindow(Handle, hDCScreen, topPos, size, hDCMemory, pointSource, 0, blend, 2)

Finally

ReleaseDC(IntPtr.Zero, hDCScreen)

If (hBitmap <> IntPtr.Zero) Then

SelectObject(hDCMemory, hOldBitmap)

DeleteObject(hBitmap)

End If

DeleteDC(hDCMemory)

End Try

End Sub

Protected Overrides ReadOnly Property CreateParams() As CreateParams

Get

Dim p As CreateParams = MyBase.CreateParams

p.ExStyle = (p.ExStyle Or &H80000)

Return p

End Get

End Property

Protected Overrides Sub WndProc(ByRef m As Message)

If (m.Msg = 132) Then

m.Result = CType(2, IntPtr)

Else

MyBase.WndProc(m)

End If

End Sub

End Class

Mike Danes  Sunday, September 10, 2006 5:18 PM

You can use google to search for other answers

Custom Search

More Threads

• Report viewer on tab
• how do i put a text box on an angle
• Timer problem?
• Codedom assembly output type
• Design Question - Offline Data Entry Storage & Upload
• Retaining and setting Multiple Sets of User Settings
• Viewing Desktop icons as thumbnails
• How To Change the behavior of the Enter key to Tab key
• Where to put code that executes after the form is shown and is not triggered by an event?
• DataGridView Column Names and Lists