2010-08-13 15 views
5

Para abreviar, intento escribir algunas notificaciones emergentes tipo tostadas (similares a Growl) que deberían aparecer junto a la bandeja del sistema y apilarlas según corresponda.VB.Net WinForms Form OnPaint() Transparency Refresh

Puedo manejar la creación de instancias/ubicación/etc ... pero quiero agregar una capacidad para tostadas no rectangulares. También me gustaría tener transparencia Alpha para que un fondo semitransparente PNG en la forma de brindis se combine con el escritorio o las ventanas detrás de él.

Entonces ... Para obtener la obvia fuera del camino:

Form.TransparencyKey no es suficiente para mis necesidades, ya que es un todo-nada o efecto de transparencia Quiero conseguir 50/50 primer plano/fondo en algunos lugares, 0/100 en otros, 100/0 en otros, etc.

Mi enfoque inicial es anular el método OnBackgroundPaint(), comentar la llamada a MyBase.OnBackgroundPaint y usar el objeto gráfico en el eventargs para dibujar exactamente lo que quiero a un formulario.

Esto parece funcionar para empezar - por el momento, estoy dibujando un rectángulo para fines de prueba, por lo que un PNG puede presentar nuevas dificultades, pero todavía no he llegado.

Lo que no he podido lograr es actualizar el gráfico: la primera vez que se muestra el formulario, se muestra perfectamente como era de esperar (sin bordes, solo algunos rectángulos flotando en un escritorio). Si muevo las ventanas detrás de la ventana transparente, la ventana transparente no se actualiza/vuelve a pintar

Creo que tengo que estar llamando a Me.Invalidate() para forzar un nuevo dibujo, pero no estoy seguro cuando debería hacer la llamada - ¿Cómo sé que una ventana detrás de mí ha cambiado su 'contenido?

¿Estoy tomando el enfoque equivocado?

Muchas gracias

Editar: He intentado poner un Me.Invalidate() dentro de un temporizador sólo para probar cómo se produce el redibujado - parece que lo hace desencadenar un redibujado pero el volver a dibujar opccurs SOBRE el fondo del formulario existente - es decir, un área que originalmente era 50% opaca ahora es 75% opaca (50% + 50% de lo que había antes)

Entonces, después de un par de Invalidate() s, mi formulario es mostrando como una caja negra - Necesito borrar el fondo del formulario antes de volver a dibujar, pero Graphics.Clear (Color) parece simplemente rellenarlo con el color especificado, y obviamente para los propósitos de esta pregunta, Colors.Tra nsparent no realmente significa transparente - Parece ser un truco usado al renderizar la ventana para "mostrar contenido de control debajo de esto" que simplemente no funciona cuando se trata del formulario en sí

In si alguien quiere replicar fácilmente, el código de mi forma es a continuación:

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 
+0

Revisé su código y me di cuenta de que dibuja el formulario con cierto nivel de transparencia [parcial]. Sin embargo, no permite el clic de las áreas "transparentes". La solución proporcionada por el artículo de CodeProject en realidad le permite ** hacer clic ** en las áreas transparentes para seleccionar ventanas bajo la forma parcial transparente. –

Respuesta

1

No es un artículo CodeProject que muestra cómo utilizar un png como "piel" del formulario. Obviamente, esto es compatible con la transparencia parcial en lugar del enfoque 50/50 ofrecido por Form.TransparencyKey.

Este es el link del artículo del proyecto de código. Estoy intentando cargar el proyecto en VB y actualizaré esta respuesta tan pronto como esté listo.


EDITAR

Aquí está la link a la versión VB.NET del artículo CodeProject he citado anteriormente.
http://www20.zippyshare.com/v/86701716/file.html

Voy a tratar de revisar su código y ver qué se puede hacer para ayudar a su situación.

+0

Con respecto al artículo. Tendrá que colocar cualquier imagen PNG de 32 bits en el formulario para mostrar el formulario con la imagen como fondo del formulario. Tendrá que anular este proceso especificando un archivo PNG en su código si desea establecer el fondo del formulario en la imagen. –

+0

Gracias - Y debería ser capaz de hackear la implementación un poco. Le agradecería que identificara el problema con mi código; me voy a echar un vistazo a su código convertido. Puede tardar algunas horas en volver a usted – Basic

+0

Bien, efecto secundario interesante: el uso de la técnica provista sí produce una forma totalmente compatible con la transparencia alfa, sin embargo, no se representan controles u otros elementos de la IU en absoluto. Además, no se reciben eventos para los controles en el formulario. ¿Tienes alguna sugerencia? – Basic