Gefilterte Eingabe: InputFilter.au3 (1.1)

  • In der Tat der naheliegendste und auch mein erster Gedanke. Aus diesem Grund habe ich das original 1.0 Beispielscript vom Eingangspost für wie weiteren Tests genommen.

    Die Funktion des Scripts ist nicht eingeschränkt. Es funktioniert auf meinem Win7 genauso perfekt wie auf den Servern. (Bild InputFilter_1, alle Bilder von einem WinSrv2012R2)
    Auf den Server OS 2012 und 2012R2 kommt es jedoch beim beenden (über das rote X) zu zwei Fehlermeldungen:

    Spoiler anzeigen


    (Bild InputFilter_2)
    Problemsignatur:
    Problemereignisname:BEX
    Anwendungsname:InputFilter Example.exe
    Anwendungsversion:0.0.0.0
    Anwendungszeitstempel:578a972e
    Fehlermodulname:StackHash_9980
    Fehlermodulversion:0.0.0.0
    Fehlermodulzeitstempel:00000000
    Ausnahmeoffset:PCH_68_FROM_ntdll+0x0003C7EC
    Ausnahmecode:c0000005
    Ausnahmedaten:00000008
    Betriebsystemversion:6.3.9600.2.0.0.400.8
    Gebietsschema-ID:2055
    Zusatzinformation 1:9980
    Zusatzinformation 2:9980f7589c88a86de280ab052029b4b0
    Zusatzinformation 3:00e9
    Zusatzinformation 4:00e9358a77afddafbdba86d810ffb2b6
    Lesen Sie unsere Datenschutzbestimmungen online:
    http://go.microsoft.com/fwlink/?linkid=280262
    Wenn die Onlinedatenschutzbestimmungen nicht verfügbar sind, lesen Sie unsere Datenschutzbestimmungen offline:
    C:\Windows\system32\de-DE\erofflps.txt

    Spoiler anzeigen


    (Bild InputFilter_3)
    Problemsignatur:
    Problemereignisname:APPCRASH
    Anwendungsname:InputFilter Example.exe
    Anwendungsversion:0.0.0.0
    Anwendungszeitstempel:578a972e
    Fehlermodulname:StackHash_bf07
    Fehlermodulversion:0.0.0.0
    Fehlermodulzeitstempel:00000000
    Ausnahmecode:c000041d
    Ausnahmeoffset:PCH_D3_FROM_USER32+0x00008E71
    Betriebsystemversion:6.3.9600.2.0.0.400.8
    Gebietsschema-ID:2055
    Zusatzinformation 1:bf07
    Zusatzinformation 2:bf0734799d58f66f0ed89a4f00b7d35f
    Zusatzinformation 3:ae60
    Zusatzinformation 4:ae60b489067d625220e9dacb62e9ac68
    Lesen Sie unsere Datenschutzbestimmungen online:
    http://go.microsoft.com/fwlink/?linkid=280262
    Wenn die Onlinedatenschutzbestimmungen nicht verfügbar sind, lesen Sie unsere Datenschutzbestimmungen offline:
    C:\Windows\system32\de-DE\erofflps.txt


    Ich kann euch nun aber auch einen Workaround zeigen. Vor dem Exit alle Inputs die mit dem Inputfilter verknüpft sind löschen. Alternativ können auch direkt die GUIs gelöscht werden.

    AutoIt
    GUICtrlDelete($cInput) ; oder alternativ GUIDelete($hMainWnd)
    Exit

    Das ist zwar kein Bugfix aber zumindest kommt schonmal keine Fehlermeldung mehr.

  • Ich kann euch nun aber auch einen Workaround zeigen. Vor dem Exit alle Inputs die mit dem Inputfilter verknüpft sind löschen. Alternativ können auch direkt die GUIs gelöscht werden.

    AutoIt
    GUICtrlDelete($cInput) ; oder alternativ GUIDelete($hMainWnd)
    Exit

    Das ist zwar kein Bugfix aber zumindest kommt schonmal keine Fehlermeldung mehr.

    Dies ist guter Programmierstil, aber daß die Schachkatze nicht aufräumt bevor ihr Programm den Speicher verlassen soll, daran hät ich nicht gedacht. Und außerdem scheint der (in die EXE eingebundene) AutoIt-Interpreter mit dem Aufräumen auch überfordert gewesen zu sein. Da tippe ich auf unverträglichkeiten 32/64 Bit bzw. unterschiedliche ntDLL-Versionen. Ich denke mit Hilfe der Daten in deinem Spoiler (speziell Adresse), kann der Bit- & Bytejongleur @Andy den/die Schuldigen ausmachen, ich schiebe solange den BUG M$ in die Schuhe.
    Wie man aber sieht muß der Bug nicht sein, wenn sauber programmiert wird.
    Übrigens: da ein Forum davon lebt, daß Lösungen zu finden sind, wäre es sehr nett, wenn du die von dir "nachgebaute" Version einstellen könntest.

    danke, (auto)Bert

  • Ah, dann war es also doch auch mein Unvermögen. Wusste nicht, dass ein GUI gelöscht werden sollte, bevor das Programm beendet wird. Exit nimmt einem die Arbeit also nicht ab. Wieder etwas gelernt, vielen Dank :)

    Mir ging auch der Gedanke mit dem Memory durch den Kopf. Es gibt im Code aber auch eine Stelle, an der der Speicher wieder Freigegeben werden soll. Jedoch habe ich es noch nicht hinbekommen, dieses IF-Statement zu triggern :/

    AutoIt: InputFilter.au3
    If $iMsg = $WM_DESTROY Then ;clean up!
    	$pOrgWndProc = $tInfoStruct.oldWndProc
    	_MemGlobalFree($pInfoStruct)
    	_WinAPI_SetWindowLong($hWnd, $GWL_WNDPROC, $pOrgWndProc)
    	Return _WinAPI_CallWindowProc($pOrgWndProc, $hWnd, $iMsg, $iWParam, $iLParam)
    EndIf

    Mit dem hochladen hast du natürlich Recht. Ich würde den Nachbau aber eher als V1.0.1 bezeichnen und sicher nicht als 1.1. Ich bin also selbst noch nicht zufrieden genug um meine kleinen Änderungen der Öffentlichkeit zur Verfügung zu stellen. Im Prinzip habe ich nur die Funktionen soweit ins UDF ausgelagert, dass im Hauptprogramm nur noch der Include und GUICtrlInputSetFilter() vorkommen muss. Ausserdem ist das Ganze noch auf meine Bedürfnisse zugeschnitten. Gebt mir noch etwas Zeit, damit ich das in etwas "allgemeines" umwandeln kann, dann ist es auch für andere sinnvoll verwendbar. Und ob es dann auch gut/schön/sinnvoll Programmiert ist… ehrlicherweise würde ich das jetzt schon mit einem Nein beantworten aber das müsst dann ihr beurteilen. ;)

  • So, ich denke in der Form könnte es wirklich einigermassen brauchbar sein. Aber auch hier mit dem Hinweis, dass es sicher nicht die schönste/beste/sauberste Lösung ist und noch >=2 Fehler enthält!

    Beim Setzen von GUICtrlInputSetFilter() kann jetzt direkt das Pattern für StringRegExp mitgegeben werden. Optional ist die Angabe von Whitelist bzw. Blacklist

    AutoIt
    GUICtrlInputSetFilter($cInput1, "^[A-zöäüÖÄÜ]{0,10}$", $INPUTFILTER_WHITELIST)
    GUICtrlInputSetFilter($cInput2, "^[A-zöäüÖÄÜ]{0,10}$", $INPUTFILTER_BLACKLIST)


    BUGS

    • Wird $INPUTFILTER_BLACKLIST mitgegeben, wird leider die Zeichenbeschränkung ignoriert. Das {0-10} nützt also Garnichts :( Warum das so ist, ist mir klar. Ich habe aber noch keine saubere Lösung dafür gefunden. Vermutlich müsste man die Zeichenbegrenzung aus $sFilterExp extrahieren und dann separat auswerten und mein Else auf Zeile 137 ergänzen.
    • Auch ist es mir noch nicht gelungen If $iMsg = $WM_DESTROY Then zu triggern.
  • Hach, nach so langer Zeit ist da nochmal jemand drauf gestoßen. ^^


    Dies ist guter Programmierstil, aber daß die Schachkatze nicht aufräumt bevor ihr Programm den Speicher verlassen soll, daran hät ich nicht gedacht.

    Das sollte eigentlich passieren. ncx8e hat die entsprechende Stelle im Code schon rausgesucht. Bei einem Exit sollte eigentlich an alle Fenster ein WM_DESTROY geschickt werden. Dieses wiederum sollte dann eben die Aufräumprozedur anstoßen. Warum genau das hier jetzt nicht klappt, ist mir ehrlich gesagt auch ein Rätsel. Das handhabe ich eigentlich immer so, sobald ich in AutoIt mit Subclassing arbeite.

    Die RegExp-Erweiterung usw. müsste sich schnell nachrüsten lassen. Ist ja schon passiert, wie ich gerade sehe. Ich kann mal schauen, wenn ich in den nächsten Tagen mal Zeit habe, kann ich das alles vielleicht nochmal durcharbeiten.

  • Mit $INPUTFILTER_WHITELIST/$INPUTFILTER_BLACKLIST als Parameter und nur einem RegEx-Pattern will mir auch keine Lösung einfallen... doch nun beendet sich das Script auch dann sauber, wenn kein GUIDelete() aufgerufen wurde. Doch hier im Forum sind ja mehrere RegEx-Experten vertreten... wäre super, wenn sich da einer/alle der Sache annehmen würden. ;)