[Beispiel] - Multi-Monitorkonfiguration ermitteln, grafisch darstellen und die Ränder der Monitore zueinander bzw. freie Ränder finden

  • In meinem Slider Projekt habe ich das Problem, das unsinnige Seiten für das Sliderfenster nicht erkannt werden.
    Unsinnig ist z.B. die Position zwischen 2 Monitoren.

    also habe ich mir etwas geschrieben was die Postionen erkennt und darstellen kann - DisplayMonitorConfiguration.au3

    Features:

    • Anzahl und Größe der Monitore erkennen und Maßstabsgerecht zeichnen
    • Die freien Ränder der einzelnen Monitore ermitteln
    • Die freien Ränder anzeigen (wieder im Maßstab)
    • Die "Zeichnung" kann Platz in der GUI angepasst werden (Slider in Demo)
    • Anzahl und Auflösung der Monitore ist "unbegrenzt"

    Bilder aus der Praxis

    Meine Bildschirmanordnung:
    [Blockierte Grafik: http://znil.net/images/e/e9/DisplayMonitor001.JPG]

    Durch das Skript erkannte Darstellung:
    [Blockierte Grafik: http://znil.net/images/5/5d/DisplayMonitor002.JPG]

    Durch das Skript erkannte freien Ränder (Mit Darstellung meiner Monitore):
    [Blockierte Grafik: http://znil.net/images/7/70/DisplayMonitor003.JPG]

    Gegenprobe: Monitor 1 und 2+3 vertauscht, 2 und 3 liegen nun auf negativen Koordninaten
    [Blockierte Grafik: http://znil.net/images/8/87/DisplayMonitor004.JPG]

    Und was das Skript daraus macht:
    [Blockierte Grafik: http://znil.net/images/e/ed/DisplayMonitor005.JPG]

    Hier der Quellcode:

    Spoiler anzeigen
    [autoit]

    ; 12 / 2011 von BLinz - http://www.autoit.de
    #include <Array.au3>
    #include <GUIConstantsEx.au3>
    #include <SliderConstants.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global $aScreenDimension ; Hier kommen die Gesamtmaße (Gesamtbreite / Höhe) der Monitore rein zwecks Maßstabsbrechnung
    Global $aAllScreenswithDimensions ; Hier stehen Anzahl, Position und Maße aller Monitore drin
    Global $iResizeFaktor ; Um welchen Faktor müssen wir verkleinern beim Zeichnen
    Global $iZeroPointX, $iZeroPointY ; Wohin mit dem Nullpunkt auf unserer Zeichenfläche (wegen Negativen Koordinaten)
    Global $LabelMonitors[1] ; Zeiger auf die Label die die Monitore darstellen
    Global $aUseableMonitorMargins[1][4] ; Hier kommt für jede der 4 Seiten eine Monitors ein Wert rein
    ; ob diese Frei ist (True) oder an einen anderen angrenzt (False)
    Global $ButtonMargins[1] ; Die Ränder werden mit Buttons dargestellt, hier die Zeiger dafür
    Global $iDrawingSize = 300 ; Grundwert, Größe der Zeichenfläche, kann per Slider angepasst werden
    Global $iOldSliderValue ; Für Echtzeitvorschau wenn der Slider bewegt wird
    Global $bShowMargins = False ; Grundwert, nicht die Ränder zeigen an denen ein Slider Fenster hin könnte

    [/autoit] [autoit][/autoit] [autoit]

    ;Wieder kleine GUI mit Koda ...
    #Region ### START Koda GUI section ### Form=c:\_autoit\z-slider\displaymonitorconfiguration.kxf
    $FormDisplayMonitorConfiguration = GUICreate("DisplayMonitorConfigurationDEMO", 615, 601, 409, 137)
    $Slider1 = GUICtrlCreateSlider(56, 496, 500, 45, BitOR($GUI_SS_DEFAULT_SLIDER,$TBS_TOP,$TBS_LEFT,$TBS_ENABLESELRANGE))
    $Label1 = GUICtrlCreateLabel("100px", 56, 480, 33, 17)
    $Label2 = GUICtrlCreateLabel("600px", 528, 480, 33, 17)
    $CheckboxShowPossibleSlider = GUICtrlCreateCheckbox("Zeige mögliche Positionen für ein Slider Fenster", 64, 544, 481, 17)
    $ButtonMonArray = GUICtrlCreateButton("Zeige Monitore-Array", 64, 568, 130, 25)
    $ButtonMarginArray = GUICtrlCreateButton("Zeige freie Seiten Array", 336, 568, 130, 25)
    $ButtonScreenDims = GUICtrlCreateButton("Zeige BildschirmDims", 200, 568, 130, 25)
    GUISetState(@SW_SHOW)
    #EndRegion ### END Koda GUI section ###

    [/autoit] [autoit][/autoit] [autoit]

    ;Slider auf Startwert setzen
    GUICtrlSetData($Slider1, ($iDrawingSize - 100) / 5)
    $iOldSliderValue = GUICtrlRead($Slider1)

    [/autoit] [autoit][/autoit] [autoit]

    ;Gesamte Bildschrimausmaße über alle Monitore ermitteln,
    ; Ergibt auch bei Monitoren mit negativen Koordinaten die Gesamtbreite / -höhe
    $aScreenDimension = WinGetPos("Program Manager")
    ;$aScreenDimension[0] = X-Position
    ;$aScreenDimension[1] = Y-Position
    ;$aScreenDimension[2] = Breite
    ;$aScreenDimension[3] = Höhe

    [/autoit] [autoit][/autoit] [autoit]

    ;_ArrayDisplay($aScreenDimension)

    [/autoit] [autoit][/autoit] [autoit]

    ;Umrechnungsfaktor für unsere (momentan 300 x 300) Fläche ermitteln
    If $aScreenDimension[2] > $aScreenDimension[3] Then
    $iResizeFaktor = $iDrawingSize / $aScreenDimension[2]
    Else
    $iResizeFaktor = $iDrawingSize / $aScreenDimension[3] ;
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    ;Nullpunkte für unsere (momentan noch 300 x 300) Fläche ermitteln
    ; 0 = 300 - 300 / ( 3600 / ( 0 + 3600))
    ; 140 = 300 - 300 / ( 3600 / ( -1680 + 3600))
    $iZeroPointX = $iDrawingSize - ($iDrawingSize / ($aScreenDimension[2] / ($aScreenDimension[0] + $aScreenDimension[2])))
    ;Nun kann es sein das ein negativer Wert herauskommt - dann in positiv wandeln
    If $iZeroPointX < 0 Then $iZeroPointX = $iZeroPointX * (-1)
    ;Das selbe noch einmal für Y Achse
    $iZeroPointY = $iDrawingSize - ($iDrawingSize / ($aScreenDimension[3] / ($aScreenDimension[1] + $aScreenDimension[3])))
    If $iZeroPointY < 0 Then $iZeroPointX = $iZeroPointY * (-1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Anzahl und Auflösung der einzelnen Monitore holen
    $aAllScreenswithDimensions = _GetMonitors()
    ; $aAllScreenswithDimensions[0][0] with number of Monitors,
    ; $aAllScreenswithDimensions[x][0] Monitor X Screen wide
    ; $aAllScreenswithDimensions[x][1] Monitor X Screen height
    ; $aAllScreenswithDimensions[x][2] Monitor X Screen Position X
    ; $aAllScreenswithDimensions[x][3] Monitor X Screen Position Y

    [/autoit] [autoit][/autoit] [autoit]

    ; Ermitteln an welchen Rändern die Monitore "zusammenstoßen" bzw. verbunden sind
    Redim $aUseableMonitorMargins[$aAllScreenswithDimensions[0][0] + 1][4]
    $aUseableMonitorMargins[0][0] = "Links"
    $aUseableMonitorMargins[0][1] = "Rechts"
    $aUseableMonitorMargins[0][2] = "Oben"
    $aUseableMonitorMargins[0][3] = "Unten"
    ; $aUseableMonitorMargins[x][0] = Left Margin
    ; $aUseableMonitorMargins[x][1] = Right Margin
    ; $aUseableMonitorMargins[x][2] = Top Margin
    ; $aUseableMonitorMargins[x][3] = Bottom Margin

    [/autoit] [autoit][/autoit] [autoit]

    ; Ermittel welcher Monitor wo steht und an welchen Seiten diese aneinander stoßen
    _GetMonitorMargins()

    [/autoit] [autoit][/autoit] [autoit]

    ;Die Monitore stellen wir durch Labels dar - Anzahl dimensonieren
    ReDim $LabelMonitors[$aAllScreenswithDimensions[0][0] + 1]
    $LabelMonitors[0] = $aAllScreenswithDimensions[0][0]
    ;Die freien Ränder durch Buttons - einfach Monitore * 4 - sind zwar bestimmt zuviel aber nie zuwenig
    Redim $ButtonMargins[$aAllScreenswithDimensions[0][0] * 4]

    [/autoit] [autoit][/autoit] [autoit]

    ;Monitore zeichnen
    _DrawMonitors()

    [/autoit] [autoit][/autoit] [autoit]

    ;Hauptschleife zur Abfrage der GUI
    While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case $GUI_EVENT_CLOSE
    Exit
    Case $CheckboxShowPossibleSlider
    ;Ok, jemand will die freien Seiten sehen (oder nicht mehr sehen)
    If BitAnd(GUICtrlRead($CheckboxShowPossibleSlider),$GUI_CHECKED) = $GUI_CHECKED Then
    $bShowMargins = True ; Anzeigen
    Else
    $bShowMargins = False ; Nicht anzeigen
    EndIf
    ;Einmal alles neu Zeichnen lassen
    _DeleteMonitors()
    _DrawMonitors()
    Case $ButtonMonArray
    _ArrayDisplay($aAllScreenswithDimensions)
    Case $ButtonMarginArray
    _ArrayDisplay($aUseableMonitorMargins)
    case $ButtonScreenDims
    _ArrayDisplay($aScreenDimension)
    EndSwitch
    ;Echtzeitvorschau des Sliders, neu zeichnen wenn der Wert sich ändert
    If $iOldSliderValue <> GUICtrlRead($Slider1) Then
    $iDrawingSize = (GUICtrlRead($Slider1) * 5) + 100 ;Slider ist von 0 bis 100, Werte aber von 100 bis 600
    ; Verkleinerungsfaktor neu ausrechnen
    If $aScreenDimension[2] > $aScreenDimension[3] Then
    $iResizeFaktor = $iDrawingSize / $aScreenDimension[2]
    Else
    $iResizeFaktor = $iDrawingSize / $aScreenDimension[3]
    EndIf
    $iOldSliderValue = GUICtrlRead($Slider1)
    $iZeroPointX = $iDrawingSize - ($iDrawingSize / ($aScreenDimension[2] / ($aScreenDimension[0] + $aScreenDimension[2])))
    If $iZeroPointX < 0 Then $iZeroPointX = $iZeroPointX * (-1)
    $iZeroPointY = $iDrawingSize - ($iDrawingSize / ($aScreenDimension[3] / ($aScreenDimension[1] + $aScreenDimension[3])))
    If $iZeroPointY < 0 Then $iZeroPointX = $iZeroPointY * (-1)
    _DeleteMonitors()
    _DrawMonitors()
    EndIf
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;löscht alle gezeichten Labels und Buttons
    Func _DeleteMonitors()
    For $i = 1 To $LabelMonitors[0]
    GUICtrlDelete($LabelMonitors[$i])
    Next
    For $i = 0 To UBound($ButtonMargins) - 1
    GUICtrlDelete($ButtonMargins[$i])
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ;Zeichnet die Monitore und ggf. Buttons Maßstabsgerecht
    ; $aAllScreenswithDimensions[0][0] with number of Monitors,
    ; $aAllScreenswithDimensions[x][0] Monitor X Screen wide
    ; $aAllScreenswithDimensions[x][1] Monitor X Screen height
    ; $aAllScreenswithDimensions[x][2] Monitor X Screen Position X
    ; $aAllScreenswithDimensions[x][3] Monitor X Screen Position Y
    Func _DrawMonitors()
    Local $j = 0
    For $i = 1 To $LabelMonitors[0]
    $LabelMonitors[$i] = GUICtrlCreateLabel($i, 16 + $iZeroPointX + Floor($aAllScreenswithDimensions[$i][2] * $iResizeFaktor), _
    16 + $iZeroPointY + Floor($aAllScreenswithDimensions[$i][3] * $iResizeFaktor), _
    Floor($aAllScreenswithDimensions[$i][0] * $iResizeFaktor), _
    Floor($aAllScreenswithDimensions[$i][1] * $iResizeFaktor), _
    BitOR($SS_CENTER,$SS_CENTERIMAGE,$WS_BORDER))
    GUICtrlSetFont($LabelMonitors[$i], 14, 800, 0, "Courier New")
    GUICtrlSetBkColor($LabelMonitors[$i], 0xffffff)
    ; $aUseableMonitorMargins[x][0] = Left Margin
    ; $aUseableMonitorMargins[x][1] = Right Margin
    ; $aUseableMonitorMargins[x][2] = Top Margin
    ; $aUseableMonitorMargins[x][3] = Bottom Margin
    If $bShowMargins = True Then
    ; links Button setzen bei Bedarf
    If $aUseableMonitorMargins[$i][0] = True Then
    $ButtonMargins[$j] = GUICtrlCreateButton("", 16 + $iZeroPointX + Floor($aAllScreenswithDimensions[$i][2] * $iResizeFaktor), _
    16 + $iZeroPointY + Floor($aAllScreenswithDimensions[$i][3] * $iResizeFaktor), _
    12, _
    Floor($aAllScreenswithDimensions[$i][1] * $iResizeFaktor))
    GUICtrlSetBkColor($ButtonMargins[$j], 0x00ff00)
    $j = $j + 1
    EndIf
    ; rechts Button setzen bei Bedarf
    If $aUseableMonitorMargins[$i][1] = True Then
    $ButtonMargins[$j] = GUICtrlCreateButton("", 4 + $iZeroPointX + Floor(($aAllScreenswithDimensions[$i][2] + $aAllScreenswithDimensions[$i][0]) * $iResizeFaktor), _
    16 + $iZeroPointY + Floor($aAllScreenswithDimensions[$i][3] * $iResizeFaktor), _
    12, _
    Floor($aAllScreenswithDimensions[$i][1] * $iResizeFaktor))
    GUICtrlSetBkColor($ButtonMargins[$j], 0x00ff00)
    $j = $j + 1
    EndIf
    ; oben setzen bei Bedarf
    If $aUseableMonitorMargins[$i][2] = True Then
    $ButtonMargins[$j] = GUICtrlCreateButton("", 16 + $iZeroPointX + Floor($aAllScreenswithDimensions[$i][2] * $iResizeFaktor), _
    16 + $iZeroPointY + Floor($aAllScreenswithDimensions[$i][3] * $iResizeFaktor), _
    Floor($aAllScreenswithDimensions[$i][0] * $iResizeFaktor), _
    12)
    GUICtrlSetBkColor($ButtonMargins[$j], 0x00ff00)
    $j = $j + 1
    EndIf
    ; unten setzen bei Bedarf
    If $aUseableMonitorMargins[$i][3] = True Then
    $ButtonMargins[$j] = GUICtrlCreateButton("", 16 + $iZeroPointX + Floor($aAllScreenswithDimensions[$i][2] * $iResizeFaktor), _
    4 + $iZeroPointY + Floor(($aAllScreenswithDimensions[$i][3] + $aAllScreenswithDimensions[$i][1]) * $iResizeFaktor), _
    Floor($aAllScreenswithDimensions[$i][0] * $iResizeFaktor), _
    12)
    GUICtrlSetBkColor($ButtonMargins[$j], 0x00ff00)
    $j = $j + 1
    EndIf
    EndIf
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Findet heraus welcher Monitor mit welcher Seite an welchen anderen Monitor stößt
    ; True = Seite Frei
    ; False = Da ist ein anderer Monitor
    ; $aUseableMonitorMargins[x][0] = Left Margin
    ; $aUseableMonitorMargins[x][1] = Right Margin
    ; $aUseableMonitorMargins[x][2] = Top Margin
    ; $aUseableMonitorMargins[x][3] = Bottom Margin
    Func _GetMonitorMargins()
    ; Alles auf True setzen (=Seite ist frei)
    For $i = 1 To $aAllScreenswithDimensions[0][0]
    For $j = 0 To 3
    $aUseableMonitorMargins[$i][$j] = True
    Next
    Next
    ;Jetzt die auf False setzen die an einen anderen Monitor stoßen (Testen immer 10 Pixel in die Richtung, daher +/- 10)
    ;Wir prüfen vom Mittelpunkt einen Monitors mit +/- 200 Pixel Toleranz nach oben/unten oder links/rechts
    For $i = 1 To $aAllScreenswithDimensions[0][0]
    For $j = 1 To $aAllScreenswithDimensions[0][0]
    If $i <> $j Then ; gegen sich selbst müssen wir nicht prüfen
    ; Horizontale Prüfungen - ausgehend von der vertikalen Mitte ( /2 ) , Toleranz 200 Pixel nach oben oder unten ( + oder - 200)
    If $aAllScreenswithDimensions[$i][3] < ($aAllScreenswithDimensions[$j][3] + ($aAllScreenswithDimensions[$j][1] / 2) - 200) And _
    ($aAllScreenswithDimensions[$i][3] + $aAllScreenswithDimensions[$i][1]) > ($aAllScreenswithDimensions[$j][3] + ($aAllScreenswithDimensions[$j][1] / 2) + 200) Then
    ; Ist neben dem linken Rand etwas?
    If ($aAllScreenswithDimensions[$i][2] - 10) < ($aAllScreenswithDimensions[$j][2] + $aAllScreenswithDimensions[$j][0]) And _
    ($aAllScreenswithDimensions[$i][2] - 10) > $aAllScreenswithDimensions[$j][2] Then
    $aUseableMonitorMargins[$i][0] = False
    $aUseableMonitorMargins[$j][1] = False
    EndIf
    ; Ist neben dem rechten Rand etwas?
    If ($aAllScreenswithDimensions[$i][2] + $aAllScreenswithDimensions[$i][0] + 10) > $aAllScreenswithDimensions[$j][2] And _
    ($aAllScreenswithDimensions[$i][2] + $aAllScreenswithDimensions[$i][0] + 10) < ($aAllScreenswithDimensions[$j][2] + $aAllScreenswithDimensions[$j][0]) Then
    $aUseableMonitorMargins[$i][1] = False
    $aUseableMonitorMargins[$j][0] = False
    EndIf
    EndIf
    ; Vertikale Prüfungen - ausgehend von der horizontalen Mitte ( /2), Toleranz 200 Pixel nach links oder rechts ( + oder - 200)
    If $aAllScreenswithDimensions[$i][2] < ($aAllScreenswithDimensions[$j][2] + ($aAllScreenswithDimensions[$j][0] / 2) - 200) And _
    ($aAllScreenswithDimensions[$i][2] + $aAllScreenswithDimensions[$i][0]) > ($aAllScreenswithDimensions[$j][2] + ($aAllScreenswithDimensions[$j][0] / 2) + 200) Then
    ; Ist oben etwas?
    If ($aAllScreenswithDimensions[$i][3] - 10) < ($aAllScreenswithDimensions[$j][3] + $aAllScreenswithDimensions[$j][1]) And _
    ($aAllScreenswithDimensions[$i][3] - 10) > $aAllScreenswithDimensions[$j][3] Then
    $aUseableMonitorMargins[$i][2] = False
    $aUseableMonitorMargins[$j][3] = False
    EndIf
    ; Ist unten etwas?
    If ($aAllScreenswithDimensions[$i][3] + $aAllScreenswithDimensions[$i][1] + 10) > $aAllScreenswithDimensions[$j][3] And _
    ($aAllScreenswithDimensions[$i][3] + $aAllScreenswithDimensions[$i][1] + 10) < ($aAllScreenswithDimensions[$j][3] + $aAllScreenswithDimensions[$j][1]) Then
    $aUseableMonitorMargins[$i][3] = False
    $aUseableMonitorMargins[$j][2] = False
    EndIf
    EndIf
    EndIf
    Next
    Next
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ; #FUNCTION# ====================================================================================================================
    ; Name ..........: _GetMonitors
    ; Description ...:
    ; Syntax ........: _GetMonitors()
    ; Parameters ....:
    ; Return values .: Array[0][0] with number of Monitors,
    ; Array[x][0] Monitor X Screen wide
    ; Array[x][1] Monitor X Screen height
    ; Array[x][2] Monitor X Screen Position X
    ; Array[x][3] Monitor X Screen Position Y
    ; Author ........: AspirinJunkie
    ; Modified ......:
    ; Remarks .......:
    ; Related .......:
    ; Link ..........: https://autoit.de/index.php?page…1717#post101717
    ; Example .......: No
    ; ===============================================================================================================================
    Func _GetMonitors()
    Local $cbMonitorEnumProc = DllCallbackRegister("MonitorEnumProc", "ubyte", "ptr;ptr;ptr;int")
    If @error Then Return SetError(1, 0, False)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]")
    If @error Then Return SetError(2, @error, False)
    Local $iCount

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($strctCount, "Count", 0)

    [/autoit] [autoit][/autoit] [autoit]

    $Ret = DllCall("User32.dll", "ubyte","EnumDisplayMonitors","ptr", 0,"ptr", 0, "ptr", DllCallbackGetPtr($cbMonitorEnumProc), "ptr", DllStructGetPtr($strctCount))
    If @error Or $Ret[0] = 0 Then Return SetError(3, @error, False)

    [/autoit] [autoit][/autoit] [autoit]

    DllCallbackFree($cbMonitorEnumProc)

    [/autoit] [autoit][/autoit] [autoit]

    $iCount = Int(DllStructGetData($strctCount, "Count"))

    [/autoit] [autoit][/autoit] [autoit]

    Local $aMonitors[$iCount+1][4] = [[$iCount]]

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $iCount
    $aMonitors[$i][0] = Int(DllStructGetData($strctCount, "Width",$i))
    $aMonitors[$i][1] = Int(DllStructGetData($strctCount, "Height",$i))
    $aMonitors[$i][2] = Int(DllStructGetData($strctCount, "left",$i))
    $aMonitors[$i][3] = Int(DllStructGetData($strctCount, "top",$i))
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Return $aMonitors
    EndFunc
    Func MonitorEnumProc($hMonitor, $hdcMonitor, $lprcMonitor, $dwData)
    Local $strctRECT = DllStructCreate("long left;long top;long right;long bottom", $lprcMonitor)
    Local $strctCount = DllStructCreate("uint Count;uint Width[12];uint Height[12];int left[12];int top[12]", $dwData)
    Local $iNumber = DllStructGetData($strctCount, "Count")
    Local $Height = Int(DllStructGetData($strctRECT, "bottom"))-Int(DllStructGetData($strctRECT, "top"))
    Local $Width = Int(DllStructGetData($strctRECT, "right"))-Int(DllStructGetData($strctRECT, "left"))

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($strctCount, "Width", $Width, $iNumber+1)
    DllStructSetData($strctCount, "Height", $Height, $iNumber+1)
    DllStructSetData($strctCount, "left", Int(DllStructGetData($strctRECT, "left")), $iNumber+1)
    DllStructSetData($strctCount, "top", Int(DllStructGetData($strctRECT, "top")), $iNumber+1)
    DllStructSetData($strctCount, "Count", $iNumber+1)
    Return True
    EndFunc
    ; ===============================================================================================================================

    [/autoit]

    Für die Darstellung über Labels habe ich mich entschieden weil ich so Text und Box in einem Objekt habe,
    die Ränder werden mit Buutons dargestellt im Vorgiff auf ein Benutzer-Setup was ich damit realisieren möchte.

    Wie immer freue ich mich auf eure Verbesserungsvorschläge :!:

    BLinz