Geht das: Integer in KeyEventArgs konvertieren?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von HHRonny.

    Geht das: Integer in KeyEventArgs konvertieren?

    Hallo,

    ich habe nun schon einige Zeit im Internet damit verbracht eine Antwort auf meine Frage zu finden. Aber nix!
    Deshalb habe ich mich hier jetzt angemeldet und hoffe hier eine Antwort von "den" Profis zu bekommen :P

    Ich möchte folgendes machen:
    In einem Fenster wird die Tasten-Eingabe abgefragt um den dazugehörigen KeyCode und die jeweilige Taste anzuzeigen.
    Das funktioniert soweit gut!
    Jetzt möchte ich aber nicht nach einem KeyCode suchen indem ich sämtliche Tasten drücke, sondern ihn über eine TextBox eingeben und mir die dazugehörige Taste anzeigen lassen.

    Ich bin jetzt kurz davor alles in einer Select Case Anweisung abzuarbeiten. Ich hoffe aber dass es eine einfachere Lösung gibt.

    Hier noch ein wenig Code um das Ganze zu verdeutlichen:

    VB.NET-Quellcode

    1. Private Sub btnViewKeyCode_Click(sender As Object, e As EventArgs) Handles btnViewKeyCode.Click
    2. 'HIER IST MEIN PROBLEM =>!
    3. 'Folgendes funktioniert leider nicht da KeyEventArgs ReadOnly ist!
    4. Me.Form1_KeyUp(Me, txtKeyCode.Text)
    5. End Sub
    6. Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
    7. 'KeyCodeAuswerten ist eine Sub die mir die Daten dann anzeigt. Funktioniert super
    8. 'solange die Parameter mit einem Druck auf eine Taste gefüllt werden!
    9. KeyCodeAuswerten(e.KeyValue, KeyCharacter)
    10. End Sub
    11. Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
    12. 'KeyCharacter ist vom Typ Char
    13. KeyCharacter = e.KeyChar
    14. End Sub


    Vielen Dank im Voraus für evtl Hilfe!

    Ps.:
    Ich benutze Visual-Studio 2015 (die Umsonst-Version) und meine Erfahrung mit VB sind mittelprächtig (früher viel mit VB6 gemacht, das war noch einfach^^). Mit komplizierten, nicht durchschaubaren Api-Code kann ich nicht viel anfangen. Wenn also auf irgendwelche Api's etc zugegriffen werden muss, bitte mit Erklärung für Doofe.
    Je höher man vor Freude springt,
    desto tiefer fällt man um auf den Boden der Tatsachen zu landen.

    VB.NET-Quellcode

    1. Dim keyCode As Integer = Integer.Parse(txtKeyCode.Text)
    2. Dim key As Keys = keyCode
    3. MsgBox(key.ToString())


    Die Keys Enumeration ist eine 1:1 Abbildung auf Key Codes
    Willkommen im Forum.
    Wir raten Einsteigern immer gleich hierzu: Visual Studio - Empfohlene Einstellungen
    Option Strict On ist wichtig, damit man Datentypen auseinander hält. In eine TextBox wird Text eingegeben. Die TextBox.Text-Eigenschaft ist vom Typ String. Also das kann eine bliebige Zeichenfolge sein. Also auch z.B. "10 Schnitzel". Das ist natürlich keine Zahl. Wenn Du versuchtst, damit zu rechnen, wirst Du bei Option Strict On direkt drauf aufmerksam gemacht, dass das nicht geht. Option Strict Off ratet einfach, was Du machen wolltest. Oft funktioniert das auch, aber wenn es mal nicht funktioniert, dann ist es sehr schwer, rauszufinden, wo das Problem tatsächlich liegt.

    Dass Me.Form1_KeyUp(Me, txtKeyCode.Text) nicht funktioniert, wird Dir mit Option Strict On vom Compiler sofort angezeigt: String kann nicht implizit zu KeyEventArgs konvertiert werden. Die Form1_KeyUp-Methode erwartet als zweiten Parameter ja ein KeyEventArgs-Objekt. Du gibst aber einen String an.

    So wie ich das sehe, möchtest Du, dass der eingegebene Text als Zahl interpretiert, das als KeyCode betrachtet wird und dann rausgefunden wird, wie dieser KeyCode mit Namen heißt.
    Das würde vom Prinzip her so funktionieren:
    • Konvertiere den String zuerst in einen Zahlentyp. Welcher das ist, findest Du ganz leicht raus, indem Du Dir im ObjectBrowser ("Objektkatalog") das Keys-Enum anguckst:

      Das "As Integer" bedeutet hier, dass alle Enum-Konstanten den Typ Integer haben.
      Konvertieren kannst Du also mit Integer.TryParse (alle primitiven Zahlen-Typen haben passende TryParse-Funktionen).
      Diese verwendet man so:

      VB.NET-Quellcode

      1. Dim Result As Integer
      2. If Integer.TryParse(DerText, Result) Then
      3. 'Konvertierung hat geklappt. Result beinhaltet jetzt den Wert.
      4. Else
      5. 'Konvertierung hat nicht geklappt. Der Text ist in irgendeiner Form ungültig.
      6. End If

    • Sag dem Compiler, dass dieser Integer eigentlich ein Wert aus dem Keys-Enum ist:

      VB.NET-Quellcode

      1. Dim KeyCode = DirectCast(DerIntegerVonOben, Keys)

      Der Compiler weiß, dass alle Enum-Konstanten im Keys-Enum vom Typ Integer sind und dass DerIntegerVonOben auch vom Typ Integer ist. Der Compiler muss also gar keinen Code generieren, der hier irgendwas konvertiert. Die Zeile dient nur dazu, dem Compiler zu erklären, dass er diesen Wert als Keys-Enum-Konstante betrachten soll.
    • Zeig den KeyCode an.
      Das könnte bei Dir die KeyCodeAuswerten-Methode machen. Wie man die genau verwendet, weiß ich jetzt nicht.
      Es würde aber auch einfach reichen, an dem KeyCode die ToString-Funktion aufzurufen. Wenn es sich um eine definierte Konstante handelt, gibt das den Namen dieser Konstante zurück. Das dürfte reichen, um rauszufinden, welche Taste es war.


    Eine Frage noch:

    HHRonny schrieb:

    da KeyEventArgs ReadOnly ist

    Wie kommst Du da drauf?
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Erstmal vielen Dank an Euch beide für diese schnellen Antworten!

    Eure Hilfestellungen funktionieren beide. Entschieden habe ich mich für die von Quadsoft da sie mir verständlicher ist und 1 Zeile weniger Code hat.

    @Niko Ortner
    Deine Hilfe ist mir aber ebenso willkommen wie ausführlich. Option Strict war in der Tat bei mir ausgestellt.
    Ich kenne diese Einstellung aber noch von VB6 (Option Explicit war es glaub ich) und hatte sie immer an.
    Vielen Dank für den Hinweis!

    So, jetzt funktioniert es also und wie sollte es anders sein? Ein neues Problem taucht auf bei dem ich mich frage wie das sein kann.

    Wenn ich obiges Beispiel ala Quadsoft umsetze

    VB.NET-Quellcode

    1. 'Entweder so:
    2. Dim keyCode As Integer = Integer.Parse(txtKeyCode.Text)
    3. Dim key As Keys = keyCode
    4. KeyCodeAuswerten(key,key.ToString())


    oder ala Niko Ortner:

    VB.NET-Quellcode

    1. Dim Result As Integer
    2. Integer.TryParse(txtKeyCode.Text, Result)
    3. Dim KeyCode = DirectCast(Result, Keys)
    4. lblKeyCodeViewStr.Text = keyCode.ToString
    5. KeyCodeAuswerten(Result, KeyCode.ToString())


    ...funktioniert das nicht mehr:

    VB.NET-Quellcode

    1. Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
    2. KeyCharacter = e.KeyChar
    3. End Sub


    ... und es wird mir statt des aktuellen KeyChar nur die letzte Zahl die ich in die TextBox eingegeben habe angezeigt. Es spielt auch keine Rolle ob ich die Werte mittels der Sub "KeyCodeAuswerten" anzeigen lasse oder direkt durch das Label mit "lblKeyCodeStr.Text".

    Wenn ich das richtig verstehe müsste doch im KeyPress-Ereignis der Wert neu zugewiesen werden und mittels der Sub "KeyCodeAuswerten" korrekt angezeigt werden Ö_Ö? Auch wenn ich den Schalter "KeyCodeEingabe" deaktiviere ist das Ergebnis dasselbe.

    Wie kann das sein?

    Hier nochmal der vollständige Quellcode mit allen drum und dran:

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Public Class Form1
    4. Declare Function GetKeyState Lib "user32" Alias "GetKeyState" (ByValnVirtKey As Int32) As Int16
    5. Private Const VK_CAPSLOCK = &H14
    6. Dim KeyCharacter As Char
    7. Dim lblShiftBC As Color
    8. Dim lblCtrlBC As Color
    9. Dim lblCapsBC As Color
    10. Dim lblAltBC As Color
    11. Dim xCharacter As String
    12. Dim keyEingabe As Boolean
    13. Dim n As Integer
    14. Dim objStreamWriter As StreamWriter
    15. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    16. lblShiftBC = lblShift.BackColor
    17. lblCtrlBC = lblCtrl.BackColor
    18. lblCapsBC = lblCaps.BackColor
    19. lblAltBC = lblAlt.BackColor
    20. keyEingabe = False
    21. If GetKeyState(VK_CAPSLOCK) = 1 Then
    22. lblCaps.BackColor = Color.LightPink
    23. Else
    24. lblCaps.BackColor = lblCapsBC
    25. End If
    26. 'machliste()
    27. End Sub
    28. Private Sub machliste()
    29. 'Pass the file path and the file name to the StreamWriter constructor.
    30. objStreamWriter = New StreamWriter("D:\Testfile.txt")
    31. For n = 0 To 255
    32. 'Write a line of text.
    33. objStreamWriter.WriteLine("case " & n & ": If (sh = True) Then " & vbNewLine &
    34. "getCharacter = " & Chr(34) & "..." & Chr(34) & vbNewLine &
    35. "Else" & vbNewLine &
    36. "getCharacter =" & Chr(34) & "..." & Chr(34) & vbNewLine &
    37. "End If" & vbNewLine &
    38. "Exit Function")
    39. Next n
    40. 'Close the file.
    41. objStreamWriter.Close()
    42. End Sub
    43. Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    44. Select Case e.KeyValue
    45. Case 16 : lblShift.BackColor = Color.LightBlue
    46. Case 17 : lblCtrl.BackColor = Color.LightGreen
    47. Case 18 : lblAlt.BackColor = Color.LightCoral
    48. End Select
    49. End Sub
    50. Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
    51. KeyCharacter = e.KeyChar
    52. End Sub
    53. Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
    54. If keyEingabe = False Then KeyCodeAuswerten(e.KeyValue, KeyCharacter)
    55. End Sub
    56. Private Sub btnViewKeyCode_Click(sender As Object, e As EventArgs) Handles btnViewKeyCode.Click
    57. 'Quadsoft
    58. '----------------------------------------------------
    59. Dim keyCode As Integer = Integer.Parse(txtKeyCode.Text)
    60. Dim key As Keys = keyCode
    61. If lblCaps.BackColor = Color.LightPink Or lblShift.BackColor = Color.LightBlue Then
    62. 'KeyCodeAuswerten(key, key.ToString())
    63. lblKeyCodeViewStr.Text = keyCode.ToString()
    64. Else
    65. 'KeyCodeAuswerten(key, LCase(key.ToString()))
    66. lblKeyCodeViewStr.Text = LCase(keyCode.ToString())
    67. End If
    68. 'Niko Ortner
    69. '----------------------------------------------------
    70. 'Dim Result As Integer
    71. 'Integer.TryParse(txtKeyCode.Text, Result)
    72. 'Dim KeyCode = DirectCast(Result, Keys)
    73. 'lblKeyCodeViewStr.Text = keyCode.ToString
    74. 'If lblCaps.BackColor = Color.LightPink Or lblShift.BackColor = Color.LightBlue Then
    75. ' 'KeyCodeAuswerten(Result, KeyCode.ToString())
    76. ' lblKeyCodeViewStr.Text = KeyCode.ToString()
    77. 'Else
    78. ' 'KeyCodeAuswerten(Result, LCase(KeyCode.ToString()))
    79. ' lblKeyCodeViewStr.Text = LCase(KeyCode.ToString())
    80. 'End If
    81. '----------------------------------------------------
    82. lblKeyCodeViewInt.Text = txtKeyCode.Text
    83. lblTextOnOff.Visible = True
    84. lblTextOnOff.Text = txtKeyCode.Text
    85. txtKeyCode.Enabled = False
    86. keyEingabe = False
    87. btnViewKeyCode.Enabled = False
    88. End Sub
    89. Private Sub KeyCodeAuswerten(i As Integer, iChar As String)
    90. Select Case i
    91. Case 8 : lblKeyCodeViewStr.Text = "Back" & vbLf & "Space"
    92. Case 9 : lblKeyCodeViewStr.Text = "Tab"
    93. Case 13 : lblKeyCodeViewStr.Text = "Enter"
    94. Case 16 : lblKeyCodeViewStr.Text = "Shift" : lblShift.BackColor = lblShiftBC
    95. Case 17 : lblKeyCodeViewStr.Text = "Ctrl" : lblCtrl.BackColor = lblCtrlBC
    96. Case 18 : lblKeyCodeViewStr.Text = "Alt" : lblAlt.BackColor = lblCtrlBC
    97. Case 19 : lblKeyCodeViewStr.Text = "Break"
    98. Case 20 : lblKeyCodeViewStr.Text = "Caps"
    99. If GetKeyState(VK_CAPSLOCK) = 1 Then
    100. lblCaps.BackColor = Color.LightPink
    101. Else
    102. lblCaps.BackColor = lblCapsBC
    103. End If
    104. Case 32 : lblKeyCodeViewStr.Text = "Space"
    105. Case 33 : lblKeyCodeViewStr.Text = "PgUp"
    106. Case 34 : lblKeyCodeViewStr.Text = "PgDown"
    107. Case 35 : lblKeyCodeViewStr.Text = "End"
    108. Case 36 : lblKeyCodeViewStr.Text = "Pos1"
    109. Case 37 : lblKeyCodeViewStr.Text = "Left"
    110. Case 38 : lblKeyCodeViewStr.Text = "Up"
    111. Case 39 : lblKeyCodeViewStr.Text = "Right"
    112. Case 40 : lblKeyCodeViewStr.Text = "Down"
    113. Case 44 : lblKeyCodeViewStr.Text = "Print"
    114. Case 45 : lblKeyCodeViewStr.Text = "Ins"
    115. Case 46 : lblKeyCodeViewStr.Text = "Del"
    116. Case 112 : lblKeyCodeViewStr.Text = "F1"
    117. Case 113 : lblKeyCodeViewStr.Text = "F2"
    118. Case 114 : lblKeyCodeViewStr.Text = "F3"
    119. Case 115 : lblKeyCodeViewStr.Text = "F4"
    120. Case 116 : lblKeyCodeViewStr.Text = "F5"
    121. Case 117 : lblKeyCodeViewStr.Text = "F6"
    122. Case 118 : lblKeyCodeViewStr.Text = "F7"
    123. Case 119 : lblKeyCodeViewStr.Text = "F8"
    124. Case 120 : lblKeyCodeViewStr.Text = "F9"
    125. Case 121 : lblKeyCodeViewStr.Text = "F10"
    126. Case 122 : lblKeyCodeViewStr.Text = "F11"
    127. Case 123 : lblKeyCodeViewStr.Text = "F12"
    128. Case 145 : lblKeyCodeViewStr.Text = "Roll"
    129. Case 220 : lblKeyCodeViewStr.Text = "^"
    130. Case Else : lblKeyCodeViewStr.Text = iChar
    131. End Select
    132. lblKeyCodeViewInt.Text = CStr(i)
    133. lblKeyCodeViewStr.Text = iChar
    134. End Sub
    135. Private Sub lblTextOnOff_Click(sender As Object, e As EventArgs) Handles lblTextOnOff.Click
    136. txtKeyCode.Enabled = True
    137. btnViewKeyCode.Enabled = True
    138. lblTextOnOff.Visible = False
    139. keyEingabe = True
    140. End Sub
    141. Private Sub txtKeyCode_TextChanged(sender As Object, e As EventArgs) Handles txtKeyCode.TextChanged
    142. On Error Resume Next
    143. If Not (IsNumeric(txtKeyCode.Text)) Then txtKeyCode.Text = ""
    144. If (CInt(txtKeyCode.Text) > 256) Then txtKeyCode.Text = "255"
    145. If (CInt(txtKeyCode.Text) < 0) Then txtKeyCode.Text = "0"
    146. End Sub
    147. End Class


    Ps.:
    @Niko Ortner nochmal:
    Auf die ReadOnly-Eigenschaft komme ich weil beim drüberfahren mit der Maus über "e.KeyValue" mir das als Hinweis angezeigt wird. Deshalb ging ich davon aus, dass das für alle Methoden des Objektes gilt.
    Je höher man vor Freude springt,
    desto tiefer fällt man um auf den Boden der Tatsachen zu landen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „HHRonny“ ()

    Quadsoft schrieb:

    du brauchst vor Allem diese switch-case anweisung überhaupt nicht. das alles steht ja bereits in der Keys enumeration.


    Wenn ich die Select Case Anweisung nicht benutze wird mir, bei den dort eingetragenen Tasten, entweder nichts angezeigt (Leertaste zb) oder irgendwelche Steuerungszeichen wie man sie aus dem Ascii-Code kennt.

    Sollte es hier eine bessere Lösung geben, dann immer her damit :)
    Je höher man vor Freude springt,
    desto tiefer fällt man um auf den Boden der Tatsachen zu landen.

    HHRonny schrieb:

    Ich kenne diese Einstellung aber noch von VB6 (Option Explicit war es glaub ich) und hatte sie immer an.
    Nein, das ist etwas ganz anderes. Verwechsel das blos nicht.

    Googel lieber mal nach Option Strict On, oder versuch das gegebene Tut wirklich zu verstehen, oder lies im Löffelmann-Buch das kapitel dazu nach. Entwickler-Ressourcen und Tools, Bücher und WebCasts - da ist allerlei gelistet, auch das Löffelmann-Buch.

    Es geht letztlich darum, ob du verschiedene Datentypen unterscheiden können wirst oder nicht.
    Wie ErfinderDesRades angemerkt hat, ist das nicht das gleiche.
    Option Strict On prüft, ob Datentypen zusammenpassen.
    Option Explicit On stellt sicher, dass verwendete Variablen deklariert sind.

    Ein Beispiel für Option Explicit Off:

    VB.NET-Quellcode

    1. Sub Test()
    2. Foo = 5
    3. MessageBox.Show(Bar)
    4. End Sub

    Weder Foo noch Bar wurden vorher mal mit Dim deklariert. Der Compiler sagt "die Variable gibt's nicht, dann erstelle ich sie eben".
    Die erste Zeile funktioniert noch mit Option Strict On, die zweite aber nicht mehr, denn Variablen, die der Compiler für Dich deklariert, bekommen automatisch den Typ Object. Und MessageBox.Show erwartet einen String -> Keine implizite Konvertierung von Object zu String erlaubt.
    Hat man also beides aus, kann man allemöglichen Blödsinn anstellen, der auch noch kompiliert, und zur Laufzeit bestenfalls eine Exception auslöst, schlimmstenfalls aber auch einfach was unerwartetes macht.

    Option Strict On (und natürlich auch Option Explicit On) ist für sauberes Programmieren absolut nötig. Deshalb ist es auch wichtig, sich die IDE so einzustellen, dass diese Optionen automatisch richtig gesetzt werden.

    Das andere, was im "Deppen-Einstellungen"-Post erklärt wird, ist der projektweite Import des Microsoft.VisualBasic-Namespaces.
    Da sind allerlei Sachen drin, die verwendet werden, wenn man VB6-Code 1 zu 1 in rüberkopiert (bzw. ein altes Projekt migriert). Beispiele wären da die MsgBox-Funktion oder so Sachen wie Split, StrPad und FileOpen. Eine unglückliche Eigenheit bei VB ist es, dass die Funktionen dann immer in der Luft rumhängen und man die überall einfach so aufrufen kann:

    Dadurch kommt man immer wieder in Versuchung, diese unnützen Funktionen zu verwenden (anstelle der eigentlich dafür vorgesehenen Klassen). Deshalb sollte man diesen Import immer entfernen. Ich bin sogar so weit gegangen, meine Projekt-Templates zu verändern und da den Import rauszunehmen. Dadurch ist der Haken bei neuen Projekten automatisch nicht mehr gesetzt.
    Es gibt in diesem Namespace trotzdem eine Sache, die nützlich ist: Steuerzeichen.
    In VB gibt es für Strings leider keine Escape-Sequenzen. Also es gibt keine einfache Möglichkeit, nicht druckbare Zeichen in einen String einzufügen. Die Microsoft.VisualBasic.ControlChars-Klasse enthält die wichtigsten Zeichen, die man so braucht. Um diese zu verwenden, kann man so einen Import verwenden:

    VB.NET-Quellcode

    1. Imports ControlChars = Microsoft.VisualBasic.ControlChars
    2. Public Class Form_Main
    3. Sub Test()
    4. MessageBox.Show("Hallo" & ControlChars.Tab & "Welt")
    5. End Sub
    6. End Class

    Dadurch muss man Microsoft.VisualBasic.ControlChars.Tab nicht immer ausschreiben, hat aber gleichzeitig auch nicht den ganzen anderen, unnötigen Krämpel rumfliegen. Wer wirklich möchte, kann hier auch das verwenden:

    VB.NET-Quellcode

    1. Imports Microsoft.VisualBasic.ControlChars
    2. Public Class Form_Main
    3. Sub Test()
    4. MessageBox.Show("Hallo" & Tab & "Welt")
    5. End Sub
    6. End Class

    Davon rate ich aber eher ab, denn dann hängen die Konstanten erst wieder zusammenhangslos in der Luft rum. "ControlChars" ist meiner Meinung nach schon kurz genug. Man kann jedoch auch einen kürzeren Namen verwenden, nur sollte halt darauf achten, dass er trotzdem aussagekräftig ist. Also Imports CC = Microsoft.VisualBasic.ControlChars ist nicht zu empfehlen, weil CC nicht aussagekräftig ist.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Also nochmals vielen Dank an Alle hier für die ausführliche Betreuung. :)

    Ich hatte zwar nicht vor mir tiefgreifende Kenntnisse in vbNet anzueignen, aber ich werde wohl auch nicht um ein paar Lektionen herumkommen wenn ich meine kleinen Tools vernünftig programmieren möchte.
    Die empfohlenen Einstellungen für Anfänger habe ich mir bereits angeschaut und umgesetzt. Die anderen verlinkten Hilfen werde ich mir auch noch ansehen und mich nach und nach so weit durchwühlen bis ich wenigsten einen sauberen Code hinbekomme.

    Hierzu habe ich auf einer der Seiten gelesen, dass es ok ist hier den Code zu posten um nach Optimierungen zu fragen. Das möchte ich hiermit tun. Ich denke bei der Deklaration der Variablen werde ich wohl noch nacharbeiten müssen. Ich bin für jeden Tipp dankbar den ich mir nicht in der Flut der Lektüren erarbeiten muss^^.

    Hier also mein fertiger Code, der dank Euch jetzt einwandfrei funktioniert!
    Habe gerade gesehen dass es dafür ein Forum gibt. Werde also dort meinen Code posten.

    Je höher man vor Freude springt,
    desto tiefer fällt man um auf den Boden der Tatsachen zu landen.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „HHRonny“ ()