Shadow/Glow goes black on invalidate

Palace

New member
Joined
Feb 2, 2014
Messages
2
Programming Experience
10+
Hi All

I have a custom form that I use for notification popups and wanted to add some shadow or glow around the edge. I managed to get something working after working out how to create a transparent form. Unfortunately when the Invalidate is called to repaint the transparency is removed.


In the Form.New I setup the styles like so
VB.NET:
SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.Opaque Or ControlStyles.UserPaint Or ControlStyles.SupportsTransparentBackColor, True)

I setup the CreateParams property to add transparent WS_EX_TRANSPARENT=&H20

VB.NET:
      Protected Overrides ReadOnly Property CreateParams() As CreateParams
        Get
            Dim cParam As CreateParams = MyBase.CreateParams
            cParam.ClassStyle = cParam.ClassStyle Or WS_EX_TRANSPARENT
            Return cParam
        End Get
    End Property


In the OnPaint of the form I create a graphics path and build up smaller and smaller shapes with gradually increasing ARGB values for the color
VB.NET:
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        If e Is Nothing Then Throw New ArgumentException("e")
        MyBase.OnPaint(e)
        _Shape = BuildPath(Me.ClientRectangle)
        Me.Region = RegionFromPath(_Shape)
        Location = BalloonLocation
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
   
        Dim rect As Rectangle
        Dim sb As SolidBrush
        For i As Integer = 0 To 6
            rect = New Rectangle(New Point(i, i), New Size(BalloonSize.Width - i * 2, BalloonSize.Height - i * 2))
            _Shape = BuildPath(rect)
            e.Graphics.DrawPath(New Pen(New SolidBrush(Color.FromArgb(24 * i, Color.Black))), _Shape)
        Next
 End Sub

This gives me a transparent form in the shape I want.
Shadow1.png


I can then paint a gradient brush to get the form I'm after.
Shadow3.png

If the Invalidate is called so OnPaint redraws I seem to lose the transparency.
Shadow2.png

I've seen a lot of posts where people have tried doing shadows with limited success. I was after a method where I could set the color or width of the shadow/glow which is why I tried this method. Many have said WinForms and shadows don't go together well and to use WPF?

Anyway if someone has a better method or knows why I lose the transparency I would be grateful.

Cheers
Peter
 

VicJ

Well-known member
Joined
Aug 12, 2008
Messages
79
Programming Experience
5-10
Hi All

I have a custom form that I use for notification popups and wanted to add some shadow or glow around the edge. I managed to get something working after working out how to create a transparent form. Unfortunately when the Invalidate is called to repaint the transparency is removed.
There are other ways to do it. I could mention Layered Windows, about which you can find information in msdn and examples in the CodeProject. But in my view they have been superseded by WPF which is more versatile (Layered Windows can't host controls) and easier. It gives you subtle drop shadows, alpha blending with the background and other graphic effects (blurring) which aren't available in GDI+.

In fact it's not all that hard to summon up a WPF window from a WinForms project. Here is a step-by-step explanation (see post #5 for the latest version) of how you can do that. I am sure you can adapt it easily to make your translucent bubbles with drop shadows without having to go all that deeply into WPF. If you have any questions about the procedure, you could post it to that thread or here.

VicJ (=BB)
 

Herman

Well-known member
Joined
Oct 18, 2011
Messages
882
Location
Montreal, QC, CA
Programming Experience
10+
It took me forever to really put some time in WPF, but I have to admit, as skeptical as I was at first I really like it now that I understand its intricacies. To me the best thing is how easy it is to design a really RIGHT user interface with just a tiny little bit of XAML. It is MUCH less code than a winforms designer, and it's soooo easy to get it to do exactly what you want, without having to call upon the API every two minutes. For example, I don't know if you have ever had to design a layered UI space (like a datagridview, an MS charts control, and a WebBrowser control all occupying the same space inside a panel with one on top depending on which button you press) but a WinForms designer it's a nightmare to work with. In WPF, it's three lines of XAML.

I'm not saying this addresses your shadowing issue directly, but I would agree with Vic here, what you want is probably much easier to do in a WPF form.
 

Palace

New member
Joined
Feb 2, 2014
Messages
2
Programming Experience
10+
Hi Guys
Yes after spending a bit of time looking around before I thought WPF would have been the way to go. Thank you for the link Vic, I'll have a look and see if I can get my head around WPF. I have looked at it a couple of times but like Herman has said it takes a bit of time to really understand it and I usually end up coming back to WinForms as I can knock it out faster. I have a Freight program that has a number of forms with layered panels that I hide and show depending on settings, so I know what you mean by a nightmare.
For the time being I've dropped the shadow property as I use the custom form as a popup on forms to highlight weights and costs that exceed values as the user enters the so it's not critical.

I'd think I'd better revisit WPF and see if I can dig a bit deeper.

Cheers
Peter
 
Top Bottom