vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
sevDataGrid - Gönnen Sie Ihrem SQL-Kommando diesen krönenden Abschluß!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück
Rubrik: Oberfläche · Effekte   |   VB-Versionen: VB2005, VB200816.02.09
Clientarea einer Form abdunkeln bzw. transparent färben

Mit diesen Funktionen erzielen einen schönen Ein-/Ausblendeffekt für Formen, wenn diese bspw. aktiviert oder deaktiviert werden, indem der Clientbereich der Form langsam abgedunkelt wird.

Autor:   Dietrich HerrmannBewertung:     [ Jetzt bewerten ]Views:  14.259 
ohne HomepageSystem:  Win2k, WinXP, Win7, Win8, Win10, Win11 Beispielprojekt auf CD 

Sie kennen den Effekt sicherlich von Windows Vista. Bei bestimmten Aktionen schaltet sich der Sicherheitsdialog der Benutzerkontensteuerung ein, wobei der komplette Desktop-Bereich abgedunkelt wird.

Diesen Effekt, also das Abdunkeln einer Form, erzielen Sie ab sofort mit nachfolgendem Code. Im unserem Beispiel wird der Clientbereich der Form autom. abgedunkelt, wenn das Fenster den Fokus verliert, weil bspw. eine andere Form angezeigt oder zu einer anderen Anwendung gewechselt wird.

Und so funktioniert's
Zur Laufzeit wird der Form ein zunächst unsichtbares PictureBox-Control hinzugefügt. Wird die Form deaktiviert, wird vom Clientbereich der Form ein "Screenshot" erstellt und der PictureBox zugewiesen. Die PictureBox wird dann vollständig über den Clientbereich gesetzt. Via Timer wird das Bild dann langsam abgedunkelt.

Ein wirklich schöner Effekt

Imports System.Drawing.Imaging
Public Class Form1
 
  ' Für Ein-/Ausblend-Effekte
  Private WithEvents timerFadeIn As Timer
  Private WithEvents timerFadeOut As Timer
 
  ' Ein-/Ausblend-Einstellungen
  Public Enum blendOpacity
    ' Beginn-Transparenz der Überdeckungsfarbe
    blendBegin = 0
 
    ' Schrittweite für Ein/Ausblenden
    blendStep = 4
 
    ' Ende-Transparenz der Überdeckungsfarbe
    blendEnd = 156
 
    ' Timer-Intervall für das Einblenden (Geschwindigkeitsregulierung)
    blendIntervalIn = 20
 
    ' Timer-Intervall für das Ausblenden
    blendIntervalOut = 10
  End Enum
 
  ' aktuelle Transparenzstufe
  Dim blendActual As Short = blendOpacity.blendBegin
 
  ' Farbe für die Überdeckung
  Dim blendColor As Color = Color.Black
  Dim iTimer As Short
 
  ' PictureBox für die Aufnahme des Screenshots
  Dim pbBlend As PictureBox
  Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
 
    ' PictureBox-Objekt erstellen
    pbBlend = New PictureBox
    Me.Controls.Add(pbBlend)
    pbBlend.SizeMode = PictureBoxSizeMode.AutoSize
    AddHandler pbBlend.Paint, AddressOf Me.pbPaint
 
    ' Wichtig!
    pbBlend.BringToFront()
 
    ' Timer für Ein-/Ausblendeffekt
    timerFadeIn = New Timer
    timerFadeIn.Interval = blendOpacity.blendIntervalIn
 
    timerFadeOut = New Timer
    timerFadeOut.Interval = blendOpacity.blendIntervalOut
  End Sub
  Private Sub Form1_Activated(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Me.Activated
 
    If pbBlend.Visible Then
      ' Einblend-Effekt starten
      timerFadeOut.Enabled = True
    End If
  End Sub
  Private Sub Form1_Deactivate(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles Me.Deactivate
 
    ' Clientbereich festlegen
    If captClient(Me, pbBlend, _
      IIf(CheckBox1.Checked, 0, Panel2.Height), _
      IIf(CheckBox2.Checked, 0, Panel1.Height), 0, 0) Then
 
      ' Ausblend-Effekt starten (abdunkeln)
      pbBlend.Visible = True
      timerFadeIn.Enabled = True
    End If
  End Sub
  Private Sub pbPaint(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.PaintEventArgs)
 
    ' Größe des Rechtecks
    Dim re As Rectangle
    With pbBlend
      re = New Rectangle(.ClientRectangle.Left, _
       .ClientRectangle.Top, _
       .ClientSize.Width, _
       .ClientSize.Height)
    End With
 
    ' Farbe
    Dim theBrush As SolidBrush = New SolidBrush( _
      Color.FromArgb(blendActual, blendColor))
 
    ' Rechteck füllen
    e.Graphics.FillRectangle(theBrush, re)
  End Sub
  Private Sub timerFadeIn_Tick(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles timerFadeIn.Tick
 
    ' Fade in Effekt
    iTimer += blendOpacity.blendStep
    If iTimer >= blendOpacity.blendEnd Then
      blendActual = blendOpacity.blendEnd
      timerFadeIn.Enabled = False
    End If
    If timerFadeIn.Enabled Then
      blendActual = iTimer
      pbBlend.Refresh()
    Else
      pbBlend.Visible = True
    End If
  End Sub
  Private Sub timerFadeOut_Tick(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles timerFadeOut.Tick
 
    ' Fade out Effekt
    iTimer -= blendOpacity.blendStep
    If iTimer <= blendOpacity.blendBegin Then
      blendActual = blendOpacity.blendBegin
      timerFadeOut.Enabled = False
    End If
    If timerFadeOut.Enabled Then
      blendActual = iTimer
      pbBlend.Refresh()
    Else
      pbBlend.Visible = False
    End If
  End Sub
  ''' <summary>
  ''' Erstellt einen Screenshot der Client-Area einer Form
  ''' </summary>
  ''' <param name="fo">Form</param>
  ''' <param name="pb">PictureBox für den Screenshot</param>
  ''' <param name="cutTop">Schnitt von oben, wenn von Clientarea noch was 
  ''' weggeschnitten werden soll</param>
  ''' <param name="cutBottom">Schnitt von unten</param>
  ''' <param name="cutLeft">Schnitt von links</param>
  ''' <param name="cutRight">Schnitt von rechts</param>
  ''' <param name="doGray">Screenshot als Graustufenbild oder nicht</param>
  Public Function captClient(ByVal fo As Form, ByVal pb As PictureBox, _
    ByVal cutTop As Short, ByVal cutBottom As Short, _
    ByVal cutLeft As Short, ByVal cutRight As Short, _
    Optional ByVal doGray As Boolean = False) As Boolean
 
    Dim w As Integer = fo.Width
    Dim cw As Integer = fo.ClientSize.Width
    Dim h As Integer = fo.Height
    Dim ch As Integer = fo.ClientSize.Height
    Dim dw As Integer = w - cw
    Dim dh As Integer = h - ch
 
    ' Wenn Höhe oder Breite < 1...
    If w < 1 OrElse h < 1 OrElse cw < 1 OrElse ch < 1 Then Return False
 
    Dim bm As New Bitmap(w, h)
 
    ' ganze Form in die Bitmap zeichnen
    fo.DrawToBitmap(bm, New Rectangle(0, 0, w, h))
    Dim bmc As New Bitmap(CInt(dw / 2), ch - cutTop)
 
    ' den Screenshot der Form beschneiden
    bmc = CropBitmap(bm, dw / 2, dh - dw / 2 + cutTop, _
      cw, ch - cutTop - cutBottom)
 
    With pb
      .Left = cutLeft
      .Top = cutTop
      If doGray Then
        ' eventuell Graustufenbild vom Screenshot machen
        .Image = GetGrayScaleImage(bmc)
      Else
        .Image = bmc
      End If
    End With
 
    Return True
  End Function
  ''' <summary>
  ''' Beschneidet ein Bitmap
  ''' </summary>
  ''' <param name="bmp"></param>
  ''' <param name="cropX">X-Koordinate</param>
  ''' <param name="cropY">Y-Koordinate</param>
  ''' <param name="cropWidth">Breite</param>
  ''' <param name="cropHeight">Höhe</param>
  Public Function CropBitmap(ByRef bmp As Bitmap, _
    ByVal cropX As Integer, ByVal cropY As Integer, _
    ByVal cropWidth As Integer, ByVal cropHeight As Integer) As Bitmap
 
    Dim rect As New Rectangle(cropX, cropY, cropWidth, cropHeight)
    Dim cropped As Bitmap = bmp.Clone(rect, bmp.PixelFormat)
    Return cropped
  End Function
  ' This method draws a grayscale image from a given Image-instance 
  ' and gives back the Bitmap of it img-  the original bitmap
  Public Function GetGrayScaleImage(ByVal img As Image) As Bitmap
    Dim grayBitmap As New Bitmap(img.Width, img.Height)
    Dim imgAttributes As New ImageAttributes()
    Dim gray As New ColorMatrix(New Single()() { _
      New Single() {0.299F, 0.299F, 0.299F, 0, 0}, _
      New Single() {0.588F, 0.588F, 0.588F, 0, 0}, _
      New Single() {0.111F, 0.111F, 0.111F, 0, 0}, _
      New Single() {0, 0, 0, 1, 0}, _
      New Single() {0, 0, 0, 0, 1}})
 
    imgAttributes.SetColorMatrix(gray)
    Dim g As Graphics = Graphics.FromImage(grayBitmap)
    g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), _
      0, 0, img.Width, img.Height, GraphicsUnit.Pixel, imgAttributes)
    Return grayBitmap
  End Function
End Class

Kurze Erläuterung zu den Funktionen:
Die Funktion captClient macht einen Screenshot von der Clientarea einer Form. Als Parameter werden erwartet:

  • Form-Objekt
  • Picturebox-Objekt, das den Screenshot aufnehmen muss
  • 4 Korrekturkoordinaten (damit kann man den Screenshot an allen vier Seiten beschneiden; bspw. die Höhe eines Toolstrips am oberen Rand und die Höhe eines StatusStrips am unteren Rand der Form)
  • Boolean-Wert, ob der Screenshot noch in ein Graustufenbild konvertiert werden soll oder nicht

Die Paint-Prozedur der PictureBox wird in Timer-Prozeduren aufgerufen. Es gibt einen TimerFadein und einen TimerFadeout.
Am Besten das Beispielprojekt einmal ausführen, da sieht man, wie das Prinzip funktioniert.

In diesem Falle wird also die Clientarea farbig 'gecaptured' und dann mit halbtransparentem Schwarz 'übermalt'. Mit den oben genannten Einstellungen kann alles beliebig gesteuert werden.

That's it, have fun.