Label zeigt Änderung nur auf Klick

  • Hallo zusammen

    ich komme bei einem Script einfach nicht weiter, gemäss allen Infos, die ich finden konnte, sollte das eigentlich funktionieren. Ich habe eine SMS-Box erstellt für den Versand von SMS. Die Idee ist nun, dass bei einem Label neben dem Feld für den Text die Anzahl eingegebener Zeichen erscheinen soll, zudem eine Anzeige, wieviel SMS es werden, jedes fasst 160 Zeichen, 800 ist die max. Anzahl Zeichen, also 5 SMS.

    Dazu schrieb ich folgendes, damits nicht zuviel wird, nur der relevante Teil:

    Nun ändert sich während der Texteingabe aber keines der zwei Labels, nur wenn man mit der Maus auf das Label klickt, kommt sofort die richtige Anzahl Zeichen und SMS, die Funktion an sich scheint also zu arbeiten.

    Aber ich komme einfach nicht drauf, warum sich der Wert in den Labels nur auf Mausklick ändert.

    Kann hier bitte jemand weiterhelfen? Vielen Dank jetzt schonmal!

    LG Dani

    Roli von Gunten

    << Alles Gute kommt von Gunten >>

  • Hier eine kleine Demo...

  • Hi Bitnugger

    ich seh hier, dass der Aufruf der Funktion über GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND") gemacht wird, ich versteh die Funktionsweise hier noch nicht ganz. Laut Referenz sind $lParam und $wParam der 1. und 2. "Message Parameter" als Hex-Wert. Leider ist mir hier nicht ganz klar, was diese Parameter genau beinhalten, 1. und 2. Message Parameter.

    Und bei den Funktionen _WinAPI_LoWord($wParam) und _WinAPI_HiWord($wParam) steht, diese liefern "the high/low word of a longword value". Mein Englisch ist hier leider nicht so gut, aber ich vermute, dass es hier nicht um Klein/Grossschrift geht, was sind denn High/Low Word?

    Roli von Gunten

    << Alles Gute kommt von Gunten >>

  • ich versteh die Funktionsweise hier noch nicht ganz.

    Das Event WM_COMMAND wird registriert und immer wenn die GUI von dem Betriebssystem die Nachricht WM_COMMAND erhält, wird die Funktion _WM_COMMAND ausgeführt.

    Dabei beinhalten die Parameter wichtige Informationen wie z.B. welche GUI angeklickt, welche Nachricht abgeschickt wurde und noch andere Informationen.

    $wParam und $lParam beinhalten wichtige Informationen zu dem Event, diese sind aber von Nachricht zu Nachricht unterschiedlich und können in der msdn nachgeschlagen werden.

    Da man nur einen 4-Byte Wert in $wParam und $lParam zur Verfügung hat, versucht man z.B. X- und Y-Koordinaten (bei WM_MOUSEMOVE) in eine Variable zu packen indem man die Variable aufteilt.

    Einige Nachrichten übergeben auch in den Variablen Pointer zu Strukturen um mehr Informationen zu übergeben.

    Dabei teilt man einen 4-Byte Wert (was ein DWORD ist, DOUBLE WORD) in 2x 2-Byte Werte auf (2x WORD).

    Mit _WinAPI_LoWord und _WinAPI_HiWord kriegt man dann die unterschiedlichen Bytes die dort gespeichert sind.

    DWORD = FF FF FF FF, WORD = FF FF.

    Rot = Low-Order Word, Blau = High-Order Word

    In diesem Fall beinhaltet das LoWord von $wParam die ID des Controls an dem ein Event ausgelöst wurde und das HiWord von $wParam den genauen Eventcode.

    Das wäre EN_CHANGE ~ EditNotify_Change(dInput).

  • Vielen Dank schonmal. Müsste ich aber anstatt des Events WM_COMMAND in meinem Fall nicht den Event WM_KEYDOWN verwenden? Ich hab nun mal folgendes zusammengeschustert, ich glaube, man merkt, dass ich ein blutiger Anfänger bin, ist erst mein zweites Script:

    Nun passiert aber gar nichts mehr, auch bei Klick ins Label bleibt die Null. Meine Vermutung ist, dass die Funktion SCHREIBEN schon gar nicht aufgerufen wird, aber warum, ist mir nicht ganz klar. In der Referenz steht zu GUIRegisterMsg(), dass in der aufzurufenden Funktion nicht mehr als 4 Variablen definiert sein dürften, sonst werde die Funktion nicht aufgerufen. Aber müssen denn überhaupt Variablen definiert sein oder gehts auch ohne? Oder liegt der Fehler vielleicht doch woanders?

    Roli von Gunten

    << Alles Gute kommt von Gunten >>

  • Hallo Oscar

    kein Problem, hab das schon selber befürchtet. Hier das ganze Script:

    Roli von Gunten

    << Alles Gute kommt von Gunten >>

    • Offizieller Beitrag

    Probier's mal so:

  • Müsste ich aber anstatt des Events WM_COMMAND in meinem Fall nicht den Event WM_KEYDOWN verwenden?

    Mit WM_KEYDOWN wird die dafür registrierte Funktion bei jedem Tastendruck aufgerufen, wenn deine GUI aktiv ist - aber nur dann, wenn kein Control den Fokus hat, dass diese Nachricht selbst auswertet, wie z.B. ein Input/Edit Control.

    WM_COMMAND wird gesendet, wenn der Benutzer ein Control (Item) aus einem Menü auswählt, wenn ein Control eine Benachrichtigungsmeldung an sein übergeordnetes Fenster sendet oder wenn ein Tastenanschlag mit einem Accelerator übersetzt wird.

    Der fett markierte Teil von WM_COMMAND... genau das brauchen wir in deinem Fall... wobei uns aber nur die Nachricht $EN_CHANGE interessiert... wenn sie von einem Input/Edit Control kommt.

    Wir müssen in der für WM_COMMAND registrierten Funktion also nur überprüfen, von welchem Input/Edit Control die Nachricht gesendet wurde und ob es $EN_CHANGE ist.

    Input/Edit Control - der hauptsächliche Unterschied ist wohl, dass ein Input Control auf nur eine Zeile beschränkt ist. Windows kennt nur Edit Controls... Input Controls gibt es nur in AutoIt. Deshalb findest du auch die Notification Constants für Input in EditConstants.au3 - somit auch $EN_CHANGE. $EN steht dann wohl für Edit Notify.

    Deine Funktion SCHREIBEN() ist aus mehreren Gründen Quatsch...

    • weil du darin die Nachrichten verarbeitest, die von GUIGetMsg() empfangen wurden und nicht die, die du durch WM_COMMAND von dem Control bekommst. Den Inhalt der Funktion kannst du also auch in deiner While-Schleife verarbeiten.
    • weil du in der Funktion keine Parameter angegeben hast, die du verarbeiten kannst: $hWnd, $iMsg, $wParam, $lParam

    $hWnd und $iMsg werden von AutoIt bereitgestellt, $wParam und $lParam von WM_COMMAND - genau in dieser Reihenfolge - und bei jedem Aufruf an diese Funktion übergeben, oder nur $hWnd und $iMsg, wenn deine Funktion nur zwei Parameter hat.

    Die Funktion wird auch aufgerufen, wenn du keinen Parameter angegeben hast, macht aber dann keinen Sinn. Den macht es nur, wenn du zumindest $wParam und/oder $lParam auswertest... und bei mehreren GUIs auch $hWnd - dass aber auch nur bedingt, wenn du $iMsg nicht auswertest.

    Ich würde dir empfehlen, immer alle Parameter anzugeben... auch wenn du sie in der Funktion nicht auswertest.

    WM_COMMAND: https://msdn.microsoft.com/de-de/library/…esktop/ms647591

  • Vielen Dank an Oscar und Bitnugger, wirklich toll, wie man hier in diesem Forum unterstützt wird, auch wenns bescheuerte Anfängerfragen sind! Nun funktionierts wunderbar.

    Eine Frage noch an Oscar: Die Anzeige der Anzahl SMS hast Du ja zur Funktion Int($iLen / 160) + 1 geändert. Nun gibts aber einen kleinen Fehler: Pro SMS kann man 160 Zeichen verwenden, dh. der SMS-Zähler sollte eigentlich erst bei 161 Zeichen zu 2 SMS wechseln, bei 321 zu 3, usw. Wenn ich Int($iLen / 161) + 1 verwende, kommts ja ab dem 2. SMS auch falsch raus. Hast Du evtl. noch eine Idee, man kann das sicher eleganter lösen, als ich es zu Anfang tat, oder?

    Roli von Gunten

    << Alles Gute kommt von Gunten >>

  • Hi.

    Dieser Ansatz fragt zyklisch das Edit ab und wenn die max. Länge überschritten wird, dann wird's einfach wieder abgeschnitten.

    Schöne Grüße, Rudi.

  • rudi

    Das ist keine gute Lösung... denn so wird die Länge ständig in Intervallen (Polling) abgefragt, auch wenn sich der Inhalt des Input-Controls nicht geändert hat. Oscar hat doch bereits gezeigt, wie es richtig gemacht wird... denn so wird die Funktion nur aufgerufen, wenn sich der Inhalt des Input-Controls geändert hat.