VB.Net WinForms表单OnPaint()透明度刷新

Bas*_*sic 5 .net vb.net gdi+ winforms

简而言之,我正在尝试编写一些吐司式弹出式通知(类似于Growl),它应该出现在系统托盘和堆栈旁边.

我可以处理实例化/位置/等...但我想为非矩形的Toast添加一个功能.我也想要Alpha透明度,所以吐司形式的半透明背景PNG将与桌面或窗口后面的窗口混合.

所以...为了明显的方式:

Form.TransparencyKey不足以满足我的需求,因为它是一个全有或全无透明效果我想在某些地方获得50/50前景/背景,在其他地方获得0/100,在其他地方获得100/0等等.

我最初的方法是覆盖OnBackgroundPaint()方法,注释掉对MyBase.OnBackgroundPaint的调用,并使用eventargs中的图形对象来准确地绘制我想要的表单.

这似乎可以开始 - 目前,我只是为了测试目的画了一些矩形,所以PNG可能会遇到新的困难,但我还没有到达那里.

我无法完成的是更新图形 - 第一次渲染表单时,它完全按照我的预期显示(没有边框,只有一些矩形浮在桌面上).如果我在透明窗口后面移动窗口,透明窗口不会更新/重新绘制

我相信我需要调用Me.Invalidate()强制重新绘制,但我不确定何时应该打电话 - 我怎么知道我后面的窗口改变了它的'内容?

我采取了错误的做法吗?

非常感谢

编辑:我尝试在一个计时器中放置一个Me.Invalidate()来测试重绘是如何发生的 - 它似乎确实触发了重新绘制,但是重新绘制会超出现有的表单背景 - 即最初的区域50%不透明现在是75%不透明(50%+以前的50%+)

因此,在几个Invalidate()之后,我的表单显示为黑盒子 - 我需要在重新绘制之前清除表单的背景但Graphics.Clear(Color)似乎只是用指定的颜色填充- 显然出于这个问题的目的,Colors.Transparent并不真正意味着透明 - 这似乎是一个技巧,当渲染窗口"显示在这下面的控制内容"时,当我们是处理表单本身

如果有人想轻易复制,我的表单代码如下:

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
Run Code Online (Sandbox Code Playgroud)

Ale*_*fie 1

有一篇 CodeProject 文章展示了如何使用 png 作为表单的“皮肤”。显然,这支持部分透明度,而不是 提供的 50/50 方法Form.TransparencyKey

这是代码项目文章的链接。我正在尝试在 VB 中上传该项目,完成后将立即更新此答案。


编辑

这是我上面引用的 CodeProject 文章的 VB.NET 版本的链接。
http://www20.zippyshare.com/v/86701716/file.html

我将尝试检查您的代码,看看可以采取哪些措施来帮助您解决问题。