Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VB.Net WinForms Form OnPaint() Transparency Refresh

Long story short, I'm trying to write some toast-style popup notifications (similar to Growl) which should appear next to the system tray and stack as appropriate.

I can handle the instantiation/location/etc... but I want to add a capability for non-rectangular toasts. I'd also like to have Alpha transparency so a semi-transparent background PNG on the toast form would blend with the desktop or windows behind it.

So... To get the obvious out of the way:

Form.TransparencyKey is not sufficient for my needs as it's an all-or nothing transparency effect I want to get 50/50 foreground/background in some places, 0/100 in others, 100/0 in yet others etc.

My initial approach is to override the OnBackgroundPaint() method, comment out the call to MyBase.OnBackgroundPaint and use the graphics object in the eventargs to draw exactly what I want to a form.

This seems to work to start with - at the moment, I'm just drawing some rectangle for testing purposes so a PNG may present new difficulties but I haven't got there yet.

What I haven't been able to accomplish is updating the graphic - The first time the form is rendered, it shows perfectly as I'd expect (no border, just some rectangles floating on a desktop). If I move the windows behind the transparent window, the transparent window doesn't update/re-paint

I believe that I need to be calling Me.Invalidate() to force a re-draw but am unsure when I should make the call - How do I know a window behind me has changed its' contents?

Am I taking the wrong approach?

Many thanks

Edit: I tried putting a Me.Invalidate() inside a timer just to test how the redraw happens - it seems that it does trigger a re-draw but the re-draw opccurs OVER the existing form background - ie an area that was originally 50% opaque is now 75% opaque (50% + 50% of what was there before)

So, after a couple of Invalidate()s, my form is showing as a black box - I need to clear the background of the form before re-drawing but Graphics.Clear(Color) seems to simply do a fill with the specified color - and obviously for the purposes of this question, Colors.Transparent doesn't really mean transparent - It seems to be a trick used when rendering the window to "show contents of control beneath this" which just doesn't work when we're dealing with the form itself

In case anyone wants to replicate easily, the code for my form is below:

Imports System.Drawing
Public Class TransparentForm

    Private Timer As Timers.Timer

    Private Sub TransparentForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer = New Timers.Timer
        AddHandler Timer.Elapsed, AddressOf Timer_Tick
        Timer.Interval = 100
        Timer.Start()
    End Sub

    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
        ''MyBase.OnPaintBackground(e)
        Console.WriteLine("BackgroundPainted")
        For x = 0 To 9
            e.Graphics.FillRectangle(
                New SolidBrush(Color.FromArgb(CInt(x / 10 * 255), 127, 127, 127)),
                CInt(x * Me.Width / 10),
                0,
                CInt(Me.Width / 10),
                Me.Height
            )
        Next
    End Sub

    Sub Timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        Console.WriteLine("Painted")
    End Sub

    Protected Overrides Sub OnInvalidated(ByVal e As System.Windows.Forms.InvalidateEventArgs)
        MyBase.OnInvalidated(e)
        Console.WriteLine("Invalidated")
    End Sub

End Class
like image 486
Basic Avatar asked Nov 14 '22 08:11

Basic


1 Answers

There is one CodeProject article that shows how to use a png as the form's "skin". Obviously, this supports partial transparency instead of the 50/50 approach offered by Form.TransparencyKey.

This is the link to the codeproject article. I'm trying to upload the project in VB and will update this answer as soon as it is done.


EDIT

Here's the link to the VB.NET version of the CodeProject article I cited above.
http://www20.zippyshare.com/v/86701716/file.html

I'll try to review your code and see what can be done to help your situation.

like image 77
Alex Essilfie Avatar answered Dec 19 '22 01:12

Alex Essilfie