Tasten an ein nicht fokussiertes Fenster senden

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

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Tasten an ein nicht fokussiertes Fenster senden

    Guten Tag,

    ihr werdet mich wohl nun öfters hier sehen. Ich hoffe, dass ist in Ordnung, da meine Fragen ziemlich basic sind. Ich versuche jedoch stätig zu lernen! Und da ihr mir bis jetzt fast immer sofort helfen konntet, ohne lange Fragen, hier mein Problem:

    Ich möchte Wörter/Sätze an ein nicht fokussiertes Fenster senden. Erstmal jedoch muss ich einen Tastendruck an das Fenster senden um eine Console zu öffnen. Diese Taste wäre "Enter".

    Nun sieht mein Code so aus:

    VB.NET-Quellcode

    1. Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    2. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    3. Public Function SendKey(ByVal window As String, ByVal key As String) As Boolean
    4. Dim hwnd As Integer, i As Integer, StringSplit As String
    5. hwnd = FindWindow(vbNullString, window)
    6. For i = 1 To Len(key)
    7. StringSplit = Mid(key, i, 1)
    8. PostMessage(hwnd, &H100, Asc(UCase(StringSplit)), 0)
    9. Next
    10. End Function


    Den Code habe ich von eine anderen Thread aus 2008. Ich habe ihn erst ein wenig umgeschrieben gehabt, bis ich dann aufgab. Ist folgender Syntax denn falsch?

    VB.NET-Quellcode

    1. SendKey("Fiesta", "{ENTER}")


    Meines Wissens sucht er ja nach den Fensternamen und nicht nach den Prozessnamen. Was mache ich hier falsch? Kann der Code überhaupt funktionieren?

    (Der Thread war Anfangs viel länger, weil ich einen PInvoke Fehler hatte und nicht auf die Datentypen geachtet habe. Nun habe ich das Problem, dass der Code einfach nicht funktioniert. Schade eigentlich.)

    /Edit:
    Nach 4 Stunden Arbeit habe ich gefühlt nichts auf die Reihe bekommen. Ist das überhaupt möglich?
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Sekki“ ()

    @Sekki: Nun, das ist jetzt nicht gerade eine Basic-Aufgabe, wie Du es nennst.
    Ich hab mal in meinen Daten gekramt, da ich den Spaß auch dauernd in der Arbeit verwenden muss.

    Zwei Sachen sind zu beachten:
    1. Du musst in den "Projekteigenschaften" -> "Anwendung" -> [Windows-Einstellungen anzeigen] die Zeile <requestedExecutionLevel level="asInvoker" uiAccess="false" /> in <requestedExecutionLevel level="requireAdministrator" uiAccess="false" /> eintragen, also mindestens soviele Rechte haben, wie Dein Zielfenster, sonst passiert gar nix, da Automatisierungen/PostMessages von niedrigberechtigten Anwendungen ignoriert werden. Alternativ es bei asInvoker belassen und Dein Visual Studio oder Deine Exe immer mit Admin-Rechten starten.
    2. Die PostMessage-Anweisung nimmt als 2. Parameter keinen Text bzw. keine Buchstaben, sondern in diesem Fall Virtual Key Codes. Nimm mal späßleshalber die 13 (= Enter) zum Testen.
    3. (Ich weiß, eigentlich sagte ich was von 2 Sachen): Schreib noch nach der 1. PostMessage (fast) die gleiche Zeile nochmal hin, nur statt mit &H100 eine mit &H101 ein. &H100 steht hier nämlich für: drück-die-Taste/KeyDown, &H101 = lass-die-Taste-los/KeyUp.

    EDIT: Mein Punkt 2 stimmt zwar, allerdings gibt es viele Übereinstimmungen von Virtual Key Codes und Buchstaben, sodass Großteile von Text wohl an das Zielfenster geschickt werden können. Allerdings wird es tricky, wenn Du Zeichen verwenden willst, die nicht mit dem Virtual Key Code übereinstimmen. Aber eins nach dem anderen, probier erstmal, wie weit Du mit dem o.g. kommst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    @VaporiZed

    Ich habe folgende Erkenntnisse gemacht:

    Mit Administratorrechten bin ich eindeutig einen Schritt weiter gekommen. Darauf hätte ich auch kommen können. So, nun folgen einige Testergebnisse:

    1:
    Funktion:

    VB.NET-Quellcode

    1. PostMessage(hwnd, &H100, Asc(UCase(StringSplit)), 0)
    2. PostMessage(hwnd, &H101, Asc(UCase(StringSplit)), 0)


    Button1:

    VB.NET-Quellcode

    1. SendKey("Fiesta", "13") und einmal SendKey("Fiesta", 13)

    Output: 1133

    Er hat also alle Buchstaben zweimal eingetippt.

    2:
    Funktion:

    VB.NET-Quellcode

    1. PostMessage(hwnd, &H100, Asc(UCase(StringSplit)), 0)


    Button1:

    VB.NET-Quellcode

    1. SendKey("Fiesta", "13") und einmal SendKey("Fiesta", 13)

    Output: 13

    Er hat alle Buchstaben nur einmal eingetippt. Soweit, so gut! Damit wäre mit Ergebnis 2 bereits die Hälfte geschafft. Jedoch simuliert er z.B ENTER nicht. Er tippt nämlich einfach "enter" ein. Mit der Zahl "13" tippt er auch nur "13" statt den Tastendruck zu simulieren. Und wenn ich PostMessage 2x schreibe mit einmal &H101, dann schreibt er erneut "1133" oder, wenn ich "enter" absende, dann schreibt er "eenntteerr".

    VB.NET-Quellcode

    1. ByVal key As String

    Kann es sein, dass hier der Fehler liegt?

    Meinst du, du weißt hier weiter?

    //Edit:
    Nun habe ich folgendes:
    Funktion:

    VB.NET-Quellcode

    1. ​Public Function SendKey(ByVal window As String, ByVal key As Integer) As Boolean
    2. Dim hwnd As Integer, i As Integer, StringSplit As String
    3. hwnd = FindWindow(vbNullString, window)
    4. For i = 1 To Len(key)
    5. StringSplit = Mid(key, i, 1)
    6. PostMessage(hwnd, &H101, 13, vbNullString)
    7. Next
    8. End Function


    Button1:

    VB.NET-Quellcode

    1. ​SendKey("Arashi3", "123")


    Er drückt zwar Enter, jedoch 2x. Hmhmhm..
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.

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

    Ja, auch. Der größte Punkt, der hier klar wird, ist, dass Du nicht Option Strict On arbeitest, sonst würde der Compiler nicht automatisch (und damit fälschlicherweise) 13 (Virtual Key Code für Enter) in "13" (also einen Text aus 1 und 3) umwandeln. Wenn Du ByVal key As Integer verwendest, macht die 13 ihren Enter-Job, daher ließe sich beides (13 und "13") per Überladung korrekt verwenden (s. folgender Code). Habe noch die korrekten PostMessage-lParam-Angaben für KeyDown und KeyUp eingefügt, hab ich damals irgendwo im Netz gefunden. Das Dilemma: Es funktioniert zwar damit korrekt, aber leider weiß ich nicht, warum bzw. was die Hex-Werte genau bedeuten.

    VB.NET-Quellcode

    1. Public Sub SendKey(ByVal key As Integer, window As String)
    2. Dim hwnd As Integer = FindWindow(vbNullString, window)
    3. PostMessage(hwnd, &H100, key, &H20020001)
    4. PostMessage(hwnd, &H101, key, &HE0020001)
    5. End Sub
    6. Public Sub SendKey(ByVal key As String, window As String)
    7. Dim StringSplit = ""
    8. Dim hwnd = FindWindow(vbNullString, window)
    9. For i = 1 To Len(key)
    10. StringSplit = Mid(key, i, 1)
    11. PostMessage(hwnd, &H100, Asc(UCase(StringSplit)), &H20020001)
    12. PostMessage(hwnd, &H101, Asc(UCase(StringSplit)), &HE0020001)
    13. Next
    14. End Sub


    Für den Moment:
    1. Dein FindWindow sollte darauf getestet werden, ob was ungleich null rauskommt, bevor dorthin Nachrichten geschickt werden. Nicht, dass jetzt alles funktioniert und später nicht mehr, nur weil die Funktion Dein Zielfenster nicht findet und daher null zurückgibt.
    2. Wenn es bisher geklappt hat, Schwein gehabt. Denn Du schickst Nachrichten wahrscheinlich an ein Hauptfenster. Wenn es die Nachrichten verarbeitet, Glück gehabt. Solche Nachrichten sollten nämlich immer an ein externes Steuerelement geschickt werden, z.B. Textbox oder was auch immer. Sonst kann es auch passieren, dass es zwar ankommt, aber vom Fenster (was Du ja mit FindWindow derzeit ansprichst), nicht verarbeitet wird, weil es gar nicht weiß, für welches seiner Steuerelemente der Text gedacht war (z.B. bei nem Fenster mit 5 Textboxen).
    Es funktioniert zwar grundsätzlich, aber es ergeben sich weitere Besonderheiten, die für später relevant werden/wären, also erstmal zweitrangig sind:
    1. AFAIK sollten diese externen Funktionen eher mit IntPtr statt mit Integer bedient werden -> Dein Code muss an mehreren Stellen angepasst werden
    2. Eine aktuelle Einbindung der externen Funktionen sollte mMn VB.Net-mäßig nicht über Declare, sondern anders erfolgen (Achtung, schon mit IntPtr):

    VB.NET-Quellcode

    1. Imports System.Runtime.InteropServices
    2. ...
    3. <DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Function PostMessage(hWnd As IntPtr, Msg As IntPtr, wParam As Integer, lParam As IntPtr) As Boolean
    4. End Function


    EDIT: Quelle für den zeitgemäßen (?) PostMessage-Funktionsaufruf (und viele weitere)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    @VaporiZed

    Ich habe jetzt seit einer Stunde versucht, deinen Code zum funktionieren zu bringen, jedoch hat es einfach nicht geklappt.. Deshalb habe ich mich mal weiter erkundigt und mit deinen Informationen das hier zusammen gewürfelt:

    VB.NET-Quellcode

    1. ​Module SK
    2. Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    3. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    4. Private Declare Ansi Function SendKey Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
    5. Public Function SendKey(ByVal window As String, ByVal key As String) As Boolean
    6. Dim hwnd As Integer = FindWindow(vbNullString, window)
    7. SendKey(hwnd, &H102, key, vbNullString)
    8. End Function
    9. Public Function SendText(ByVal window As String, ByVal key As String) As Boolean
    10. Dim hwnd As Integer, i As Integer, StringSplit As String
    11. hwnd = FindWindow(vbNullString, window)
    12. For i = 1 To Len(key)
    13. StringSplit = Mid(key, i, 1)
    14. PostMessage(hwnd, &H101, Asc(UCase(StringSplit)), 0)
    15. Next
    16. End Function
    17. End Module


    Das ist ein Module, mit dem ich Tasten wie "Enter" simulieren und Strings eintippen lassen kann. Es funktioniert alles WUNDERBAR. Es gibt keinerlei Probleme, bis auf ein einziges: Folgendes Symbol: "/" wird bei "SendText" einfach nicht beachtet und nicht mitgetippt. Kannst du mir hierbei helfen? Und kannst du mir vielleicht noch mein Module ein wenig verschönern? Es ist meiner Meinung nach ein totales Chaos, doch ich traue mich nicht, es zu verkleinern.

    Danke dir vielmals für deine Hilfe, ohne dich hätte ich niemals so weit kommen können. Niemals. Und ja, ich habe mal von "Option Strict On" gehört, doch ich bin nie dazu gekommen, es zu aktivieren. Wäre sicherlich mal von Nöten. Danke für die Information!
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.
    Hm, schade, dass mein Code nicht läuft. Aber gut, dass Du schon selber weitergemacht hast und weit gekommen bist.
    Das mit dem / ist genau der Punkt, den ich in meinem Edit in Post 2 vermerkt habe. Wenn ein Zeichen kein Äquivalent auf der Tastatur hat, wird das nix. Die Funktion PostMessage/SendMessage schickt mit &H100 einen Tastendruck der angegebenen Taste an ein anderes Fenster. Da es nicht auf jeder Tastatur an der selben Stelle ein / gibt, gibt es dafür auch keinen passenden Virtual Key Code. Wenn am Ziel allerdings nur Dein Text stehen soll, dann kannst Du das auch komplett anders machen: SendKey(hwnd, &HC, 0, "Hier könnte IHR Text mit Sonderzeichen (z.B. /) stehen"). Während &H100 für "schicke Tastendruck" steht, steht &HC für "schicke Text", siehe allgemeinen MSDN-Eintrag. Wenn Du vorhandenen ergänzen willst, geht das zwar auch, ist aber ein bisken aufwendiger, da man sich erst den vorhandenen Text mit WM_GETTEXT und nochn bisken Code drumherum holen muss, seinen Text ergänzt und dann wieder den ganzen ans Zielfenster zurückschickt.

    Nochwas zu PostMessage/SendMessage: Die Wirkung auf das Zielfenster ist die gleiche, jedoch nicht auf Dein Programm selbst. PostMessage ist eine Fire-And-Forget-Funktion. Sie ist ein Postbote, der Dir nen Brief in den Briefkasten steckt. Sie schickt die Nachricht und macht dann gleich in Deinem Programm weiter. SendMessage ist der selbe Postbote, nur mit nem Einschreiben für Dich. Er wartet auf Unterschrift, bevor er weiterfährt; will heißen die Funktion schickt die Nachricht ab und wartet auf Rückmeldung des Zielfensters, dass die Nachricht verarbeitet wurde. Sollte das Zielfenster grad viel zu tun haben, wartet SendMessage, bis es die Rückmeldung hat und Dein Programm stockt. Wähle daher selber weise, was Du brauchst.

    Und zu Deinem Modul: Es sind nur Kleinigkeiten, die ich verändern würde. Chaos ist was anderes. Um die Declare-Anweisungen kommst Du nicht drumrum. Du könntest sie in einen #Region...#End Region-Block packen und ausblenden, aber das ist nur Kosmetik. Oder statt nem Module ne Klasse nehmen und dann auf 2 Dateien aufteilen, eine mit den Declare-Anweisungen, eine mit den Funktionen (bzw. dann Klassen-Methoden) und beide Dateien mit Partial Class InputSimulation (oder nem anderen Klassennamen) versehen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    @VaporiZed

    Ich habe es nun eine Weile lang versucht, jedoch funktioniert es leider nicht. Egal, wie ich was abändere, es funktioniert einfach nicht. Dieser Code mag mich einfach nicht mehr. Ich habe so vieles versucht. Ich habe nun mal wieder etwas gegoogled und versucht, herauszufinden, wie ich es nun zum funktionieren bringe. Ich habe dir mal eine Nachricht mit dem Link gesendet, den ich gefunden habe. Ich kann nicht ganz verstehen, was ich nun an meinem Module ändern muss. Meinst du, du könntest mir da helfen?

    SendKey funktioniert für mich perfekt! SendText müsste nur umgeschrieben werden. Ugh, ich kann bald nicht mehr, mein Kopf macht das nicht mit. Das ich an sowas hängen bleibe ist für mich einfach nur Zeitverschwendung. Ich hoffe, du kannst mir wirklich weiterhelfen.

    Edit:
    Ich habe noch nicht aufgegeben!

    VB.NET-Quellcode

    1. Module SK
    2. Public Sub ResponsiveSleep(ByRef iMilliSeconds As Integer)
    3. Dim i As Integer, iHalfSeconds As Integer = iMilliSeconds / 500
    4. For i = 1 To iHalfSeconds
    5. Threading.Thread.Sleep(500) : Application.DoEvents()
    6. Next i
    7. End Sub
    8. Private Const PROCESS_VM_READ = (&H10)
    9. Private Const PROCESS_VM_WRITE = (&H20)
    10. Private Const PROCESS_VM_OPERATION = (&H8)
    11. Private Const PROCESS_QUERY_INFORMATION = (&H400)
    12. Private Const PROCESS_READ_WRITE_QUERY = PROCESS_VM_READ + PROCESS_VM_WRITE + PROCESS_VM_OPERATION + PROCESS_QUERY_INFORMATION
    13. Public Const WM_KEYDOWN = &H100
    14. Public Const WM_KEYUP = &H101
    15. Public Const WM_CHAR = &H102
    16. Public Const VK_CONTROL = &H11
    17. Public Const VK_A = &H41
    18. Public Const VK_E = &H45
    19. Public Const VK_F1 = &H70
    20. 'SendText
    21. Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
    22. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    23. Private Declare Ansi Function SendKey Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
    24. Public Function SendKey(ByVal window As String, ByVal key As String) As Boolean
    25. Dim hwnd As Integer = FindWindow(vbNullString, window)
    26. SendKey(hwnd, &H102, key, vbNullString)
    27. End Function
    28. Public Function SendText(ByVal window As String, ByVal key As String) As Boolean
    29. Dim hwnd As Integer, i As Integer, StringSplit As String
    30. hwnd = FindWindow(vbNullString, window)
    31. For i = 1 To Len(key)
    32. StringSplit = Mid(key, i, 1)
    33. PostMessage(hwnd, WM_CHAR, Asc(UCase(StringSplit)), 0)
    34. Next
    35. End Function
    36. End Module
    Mein Module sieht nun so aus! Ich habe nun "WM_CHAR" genutzt, statt nur "&H102"! Ich habe nicht gewusst, dass es solch einen Effekt auf den Output hat. Nun brauche ich tatsächlich nur noch eine Kleinigkeit!

    /test = /TEST
    /test 123 = /TEST 123

    Er schreibt Buchstaben GROß, jedoch schreibt er Zahlen so, wie sie sein müssen. Wie kann ich dem Programm nun sagen, dass er die Buchstaben ebenfalls beachten soll, wie sie dort stehen?
    (ResponsiveSleep habe ich eingebaut, weil er nicht zu schnell sein soll)

    Edit:
    So, auch das habe ich nun gemeistert! Ich habe das "UCase" vollkommen übersehen. So, nun werde ich erstmal damit etwas arbeiten und dir/euch dann Ergebnisse schildern, falls etwas nicht funktioniert! Ich bedanke mich an dem Punkt sehr bei dir! Ich kann immer noch nicht glauben, dass man so viel beachten muss. Wenigstens habe ich viel dazugelernt! Falls du noch Tipps hast zum Module, dann nur zu! Lieber früher als später..
    Wenn ich eine Frage stelle, habe ich sie bereits gegooglet. Ja, es kommt vor, dass ich die Antwort übersehe. Ja, es kommt vor, dass ich sie nicht verstehe. Deshalb bin ich hier. Wenn dies eure Frage war, dann antwortet bitte nicht. Es stiehlt sämtliche Motivation.

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

    Na, das klingt ja mal ganz gut. Jetzt zu den Feinheiten Deines Codes. Ich nehme einfach mal Deinen letzten Post als Ausgangspunkt:
    allgemein: Schreib mal Option Infer On in die allererste Zeile. Dann weiß der Compiler automatisch, wenn Du Dim i = 0, s = "" schreibst, dass i ein Integer und s ein String ist.
    Zeile 28, 33: Public Function -> Public Sub, da Deine Noch-Funktionen gar keine Werte zurückgeben
    Zeile 29: Dim hwnd = FindWindow(vbNullString, window), ggf. statt vbNullString auch Nothing, ist ja das Gleiche. In der nächsten Zeile If hwnd = 0 Then Exit Sub. Eben falls Dein Programm nix findet.
    Zeile 30: Da steht noch &H102, wahrscheinlich in Deinem aktuellen Code schon WM_CHAR.
    Deine SendText-Funktion mal etwas anders:

    VB.NET-Quellcode

    1. Public Sub SendText(ByVal window As String, ByVal key As String)
    2. Dim hwnd = FindWindow(vbNullString, window)
    3. If hwnd = 0 Then Exit Sub
    4. For Each lp_Char In key
    5. PostMessage(hwnd, WM_CHAR, lp_Char, 0)
    6. Next
    7. End Sub


    Ich hab mich grad gewundert, warum es mit der Entertaste bei Dir funktioniert, obwohl Du in beiden Funktionen den key als String übergibst. Option Strict On ist noch nicht aktiviert. Daher interpretiert er bei SendKey den übergebenden Text als Zahl. Es mag für den Anfang ungewohnt sein, Option Strict auf On zu setzen, da man viele Kleinigkeiten umbasteln muss, hilft Dir aber vieles zu vermeiden, was durch heimliche Umwandlung durch Option Strict Off quasi ohne Dein Wissen passiert, siehe Post 4.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()