Diamo forma personalizzata e colori trasparenti alle nostre finestre con VB.NET : gli shaped form


Scritto da Giovanni Bernardo in data 3 aprile 2009

Molte applicazioni presentano finestre con forme stravaganti e bordi trasparenti, realizzare una cosa del genere con VB.NET è una cosa piuttosto semplice. Abbiamo innanzitutto bisogno di un’immagine che dovrà fungere da sfondo per la nostra finestra, rigorosamente in formato GIF o PNG (da scartare le JPG che a causa della compressione possono presentare artefatti che inficerebbero l’effetto trasparenza o le BMP a causa della memoria occupata). L’immagine deve essere disegnata in maniera tale da avere un’area (ovvero quella che vogliamo sia invisibile) di un colore uniforme, un’immagine del genere disegnata con photoshop è l’ideale:

immagine_per_shaped_form

Come vedete l’area intorno alla stella è colorata in maniera uniforme (tenete a mente il codice esadecimale del colore utilizzato, in questo caso è  FF00FF). Nulla ci vieta di utilizzare immagini al posto di forme come in questo caso, l’importante (per ottenere un certo impatto visivo) è quello di fare in modo che lo sfondo sia di un colore uniforme e soprattutto non utilizzato nel resto dell’immagine (ovviamente se abbiamo un’immagine al cui interno ci sono aree bianche e lo sfondo che vogliamo rendere trasparente è bianco, si otterranno degli effetti antiestetici, dal momento che tutto ciò che nell’immagine è bianco viene reso trasparente). Per questo motivo spesso (soprattutto nelle GIF animate) viene sempre scelto il colore FF00FF, perchè difficilmente tale colore è presente nell’immagine.

Avviamo quindi una nuova applicazione Windows Forms, per dare forma a un Form (scusate l’inevitabile cacofonìa) abbiamo bisogno principalmente di settare soltanto 3 proprietà:

  • FormBorderStyle
    Deve essere impostata su “None” , in maniera da non avere bordi intorno al Form
  • BackgroundImage
    ovvero l’immagine di sfondo del form, che possiamo importare come risorsa locale o risorsa del progetto
  • TransparencyKey
    che ci permette di impostare il colore trasparente. In questo caso tale proprietà verrà impostata direttamente nel metodo Load del form:

    Me.TransparencyKey = System.Drawing.Color.FromArgb(255, 0, 255)

    (da notare che il codice del colore trasparente da esadecimale: FF00FF è stato convertito in RGB: 255,0,255)

Fatto questo dobbiamo quindi settare larghezza e altezza del form per fare in modo che l’immagine entri tutta, e impostare la proprietà BackColor dei vari controlli su Transparent e il più è fatto. Il risultato, utilizzando belle immagini, è di sicuro effetto:

shaped_form_demo

Ovviamente anche se il contorno del form è invisibile, è ancora sensibile.

Avviando l’applicazione in modalità debug però ci accorgiamo da subito di 2 problemi: Il form, mancando del bordo non può essere spostato, il form non può essere chiuso.

Per quanto riguarda la questione della chiusura, il sistema è semplice, possiamo mettere un pulsante o una label che lanciano il metodo Close, io personalmente in un form del genere preferisco piuttosto gestire il doppio click per effettuarne la chiusura.

Per lo spostamento, invece, dobbiamo ricorrere ad un artifizio: gestire gli eventi MouseDown, MouseUp e MouseMove sul form e su qualsiasi altro oggetto sul quale l’utente può cliccare senza problemi (ad esempio eventuali label non associate a nessuna funzione).

Il codice utilizzato è il seguente:

Public Class formMain
 
    ' Variabili utilizzate per gestire il drag
    Dim DragEnabled As Boolean
    Dim MouseX As Integer
    Dim MouseY As Integer
 
    Private Sub formMain_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown, Label1.MouseDown
 
        ' Click sul form o sulla Label1
 
        ' Imposto la mia variabile di controllo
        DragEnabled = True
 
        ' Recupero la posizione attuale del mouse
        MouseX = Windows.Forms.Cursor.Position.X - Me.Left
        MouseY = Windows.Forms.Cursor.Position.Y - Me.Top
 
    End Sub
 
    Private Sub formMain_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove, Label1.MouseMove
 
        ' Se la mia variabile di controllo è impostata su vero
        ' muovo il form insieme al mouse
 
        If DragEnabled Then
 
            Me.Top = Windows.Forms.Cursor.Position.Y - MouseY
            Me.Left = Windows.Forms.Cursor.Position.X - MouseX
 
        End If
 
    End Sub
 
    Private Sub formMain_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp, Label1.MouseUp
 
        ' Rilascio del mouse sul form o sulla label 1
        ' Imposto su Falso la mia variabile di controllo
        DragEnabled = False
 
    End Sub
 
' ... resto del codice
 
End Class

In pratica la soluzione come si vede è molto elementare, viene settata una variabile globale (DragEnabled) su Vero quando viene effettuato il click sul form o su un altro elemento inutilizzato (Label1 nel nostro esempio), in questo istante viene anche memorizzata la posizione del mouse. Quando il mouse viene mosso, si scatena l’evento associato per cui il form viene spostato in contemporanea (il movimento del form viene effettuato soltanto se la nostra variabile di controllo è vera), quando il mouse viene rilasciato, la variabile di controllo viene resettata, altrimenti il form continuerebbe a muoversi.

Su MSDN, in questa pagina,  c’è un esempio simile, che utilizza un altro codice per il movimento del form.

In allegato il progetto completo : Shaped Form Demo (186)

Articoli che potrebbero interessarti:

L'articolo ti è piaciuto o ti è stato utile per risolvere un problema? Supporta e mantieni in vita questo sito, ci basta soltanto un caffè o una birra

  1. #1 da Benito il 26 settembre 2009

    Sito molto interessante

  2. #2 da Giacomo il 18 maggio 2010

    NON RIESCO A UTILIZZARE IL TUO CODICE IN QUANTO VB (2010) NON MI FA IMPOSTARE IL BACKCOLOR SU TRASPARENT! HELP

    • #3 da Giovanni Bernardo il 18 maggio 2010

      Cerchiamo di non scrivere tutto in maiuscolo. Mi pare strano che VB2010 non abbia la possibilità di impostare “transparent” nella proprietà “BackColor”. Io uso ancora la versione vecchia di VB.NET e me lo fa fare. Bisogna vedere in rete se qualcun altro ha questo problema o se hanno deciso di togliere questa proprietà e/o farla impostare in maniera differente.

  3. #4 da Giacomo il 19 maggio 2010

    Scusa Giovanni ma sono molto euforico di aver trovato questo tuo prezziosissimo estratto! Ho cercato sul web e non ho trovato nessuna discussione che mi sappia dare una soluzione concreta al problema.

    Ho provato a inserire codici nel frame quali:

    Me.BackColor = Color.Transparent

    ma non funziona… Posso sapere quale versione di Visual Studio Utilizzi?

  4. #6 da Giacomo il 19 maggio 2010

    Ho risolto! … Anche se in un modo abbasta particolare e scomodo ( non posso usare immagini con trasparenze ) ma comunque ho risolto! Imposto il BackColor su un colore (Magenta) e la TransparencyKey sullo stesso colore del BackColor… in questo modo si annullano e diventa trasparente! ;)

    Per il resto il tuo codice va benissimo! Grazie ancora

    • #7 da Giovanni Bernardo il 19 maggio 2010

      Aspetta un attimo!
      Il form non lo puoi rendere trasparente, lo rendi trasparente col sistema che hai appena detto e che ho pure esposto nel mio articolo e fino a qui non ci piove, sta scritto chiaramente. Quelli che devi rendere trasparenti con il backcolor sono i controlli, non il form.

  5. #8 da Giacomo il 20 maggio 2010

    Ecco dove cascava l’asino! :O Il BackColor trasparente riguardava i controlli non il frame! Scusami allora del fraintendimento… Grazie ancora

(non verrà pubblicata)
  1. Ancora nessun trackback

Fusion theme by digitalnature | Articoli (RSS) e Commenti (RSS) ^