WM_Command - Message beim Verlieren des Fokus abfangen.

  • Hey,

    hab ein Problem :(

    In einer Eingabemaske, bestehend aus mehreren Input's, soll der Inhalt geprüft werden (Beispiel: Input2 darf nur Zahlen enthalten oder ähnliches).
    Am sinnvollsten wäre es (denke ich mal :S ) sobald der Fokus vom Input genommen wird gleich den Inhalt zu prüfen.

    Laut googel ist die Windows Message WM_Command dafür geeignet, es wird auch eine Message ausgegeben sobald der Fokus geändert wird!
    Leider werden ich aus der Dokumentation nicht schlau, was genau ist die Message für einen Fokus wechsel? Wie kann ich diese Message den einzelen Controls zuweisen?

    Beispiel:

    Spoiler anzeigen
    [autoit]


    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <EditConstants.au3>
    #include <StructureConstants.au3>
    #include <WinAPI.au3>

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

    $sHeader = "Input1|Input2|Input3"
    Global $hGui = GUICreate("", 400, 400, -1, -1)
    Global $aHeader = StringSplit($sHeader, '|') ; Überschriften-Array
    Global $aNew[$aHeader[0]] ; Array für die Input-IDs
    Global $aInputWidth[$aHeader[0]] = [100, 100, 100] ; hier die Länge (in Pixel) der Inputfelder eintragen
    Global $xPos = 20
    For $i = 1 To $aHeader[0]
    GUICtrlCreateLabel($aHeader[$i], $xPos + 2,200, 110, 20) ; Überschriften-Label erstellen
    GUICtrlSetFont(-1, 8, 400, 0, 'Verdana') ; Schriftgröße und -art der Überschriften festlegen
    $aNew[$i - 1] = GUICtrlCreateInput("", $xPos, 220, $aInputWidth[$i - 1], 20, Default, $WS_EX_STATICEDGE) ; Eingabefelder erstellen
    GUICtrlSetFont(-1, 10, 600, 0, 'Verdana') ; Schriftgröße und -art der Eingabefelder festlegen
    $xPos += $aInputWidth[$i - 1] + 5
    Next

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

    GUISetState(@SW_SHOW, $hGui)
    GUIRegisterMsg($WM_Command ,"WM_COMMAND")

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

    While 1
    $nMsg = GUIGetMsg(1) ; Message-Event holen (1) = erweiterter Modus

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

    Switch $nMsg[0] ; anhand der Control-ID das entsprechende Case aufrufen

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

    #Region Schließen
    Case $GUI_EVENT_CLOSE ; User hat auf das Schließen-Symbol geklickt (bzw. die ESC-Taste gedrückt)
    Switch $nMsg[1] ; erweiterte Abfrage für welches Fenster
    Case $hGui ; User will das Hauptfenster schließen
    exit

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

    EndSwitch

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

    #EndRegion Schließen
    EndSwitch

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

    WEnd

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    MsgBox(1, "", $iwParam)
    EndFunc ;==>WM_COMMAND

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

    ;jedes Input soll, sobald es den Fokus verliert mit einer anderen Funktion überprüft werden.
    Func _Checkinput1()
    ;
    Endfunc
    Func _Checkinput2()
    ;
    Endfunc
    Func _Checkinput3()
    ;
    Endfunc

    [/autoit]

    Wäre super wenn mir dazu auch jemand erklären könnte wo man selbst nachlesen kann wie die verschiedenen Messagecodes zu behandeln sind.

    Gruß nuts

    • Offizieller Beitrag

    Hier mal ein Bsp., ist zwar für Edit erstellt, aber wirkt analog bei Input.
    Einfach mal mit TAB den Fokus zwischen Input und Button wechseln (oder den Button Klicken). Die Änderung siehst du im Fenstertitel.

    Spoiler anzeigen
    [autoit]

    #include <EditConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    Opt("GUIOnEventMode", 1)
    Global $eventCount = 0
    $Form1 = GUICreate("Form1", 633, 454, 193, 115)
    GUISetOnEvent($GUI_EVENT_CLOSE, '_ende')
    ;~ $hEdit = GUICtrlCreateEdit("", 100, 60, 417, 289)
    $hEdit = GUICtrlCreateInput('', 100, 60, 400)
    GUICtrlSetData(-1, "Edit1")
    $b = GUICtrlCreateButton('Button', 10, 10, 60, 20)
    GUISetState(@SW_SHOW)

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

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    While 1
    Sleep(100)
    WEnd

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

    Func _ende()
    Exit
    EndFunc

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

    Func _ShowEvent($Event)
    $eventCount += 1
    WinSetTitle($Form1, '', '[' & $eventCount & '] Event: >> ' & $Event & ' <<')
    EndFunc

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

    Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit
    If Not IsHWnd($hEdit) Then $hWndEdit = GUICtrlGetHandle($hEdit)
    $hWndFrom = $ilParam
    $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
    $iCode = BitShift($iwParam, 16) ; Hi Word
    Switch $hWndFrom
    Case $hEdit, $hWndEdit
    Switch $iCode
    Case $EN_ALIGN_LTR_EC ; Sent when the user has changed the edit control direction to left-to-right

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

    Case $EN_ALIGN_RTL_EC ; Sent when the user has changed the edit control direction to right-to-left

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

    Case $EN_CHANGE ; Sent when the user has taken an action that may have altered text in an edit control
    _ShowEvent('Inhalt Edit geändert')
    Case $EN_ERRSPACE ; Sent when an edit control cannot allocate enough memory to meet a specific request

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

    Case $EN_HSCROLL ; Sent when the user clicks an edit control's horizontal scroll bar
    _ShowEvent('Horizontal Scroll')
    Case $EN_KILLFOCUS ; Sent when an edit control loses the keyboard focus
    _ShowEvent('Focus verloren')
    Case $EN_MAXTEXT ; Sent when the current text insertion has exceeded the specified number of characters for the edit control

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

    ; This message is also sent when an edit control does not have the $ES_AUTOHSCROLL style and the number of characters to be
    ; inserted would exceed the width of the edit control.
    ; This message is also sent when an edit control does not have the $ES_AUTOVSCROLL style and the total number of lines resulting
    ; from a text insertion would exceed the height of the edit control
    Case $EN_SETFOCUS ; Sent when an edit control receives the keyboard focus
    _ShowEvent('Focus erhalten')
    Case $EN_UPDATE ; Sent when an edit control is about to redraw itself
    ;~ MsgBox(0, '', 'Updated')
    Case $EN_VSCROLL ; Sent when the user clicks an edit control's vertical scroll bar or when the user scrolls the mouse wheel over the edit control
    _ShowEvent('Vertikal Scroll')
    EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit]
  • Super, danke!

    Zum besseren Verständnis, sonst wirds bei der nächsten Abwandlung wieder nichts.

    Was passiert in Zeile 32 & 33? Dabei wird die abgefeuerte Message in die richtige Form gebracht - nur nach welcher Vorgabe?
    Die verwendbaren Messages EN_KILLFOCUS usw. muss man sich dann fürs entsprechende Control ergoogeln (bzw. man schaut sich die includes an)?

    • Offizieller Beitrag

    OK, hier mal der eigentliche Inhalt einer Msg:

    [autoit]

    WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
    $hWnd ; - Handle des Fensters, das die Nachricht bringt
    $iMsg ; - die Nachricht
    $iwParam ; - DWORD-Wert
    ; Lo = ID des Ctrl, das die Nachricht bringt
    ; Hi = Code der Nachricht
    $ilParam ; - Handle des Ctrl, das die Nachricht bringt

    [/autoit]


    Übersicht WM-Codes
    Über Messages

  • Aha jetzt kommt Licht ins Dunkel. :thumbup:

    In Zeile 32 & 33 wird dann das Doppelwort getrennt. Die ersten 16 Bits sind das Lowword und die letzten das Highword.
    Naja Zeile 32 ist noch unklar :D aber das muss ich morgen nochmal genauer untersuchen.