GUIRegisterMsg($WM_KEYDOWN, ...) funktioniert nicht. KEYUP geht.

  • Hallo,

    Ich habe ein Problem mit WM_KEYDOWN,
    im folgenden Skript reagiert nur die WM_KEYUP Funktion auf eine Eingabe.
    Ich habe es auf Win XP und Win 7 getestet, auf keinem von beiden funktioniert es,
    auch wenn ich es kompiliere nicht.


    [autoit]

    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>

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

    Opt("GUIOnEventMode", 1)

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

    $GUI = GUICreate("GUI", 960, 540, Default, Default)
    GUISetOnEvent($GUI_EVENT_CLOSE, "Event_Close", $GUI)
    GUIRegisterMsg($WM_KEYUP, "WM_KEYUP")
    GUIRegisterMsg($WM_KEYDOWN, "WM_KEYDOWN")
    GUISetState(@SW_SHOW)

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

    While 1
    Sleep(100)
    WEnd

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

    Func WM_KEYUP($hWnd, $Msg, $wParam, $lParam)
    If $wParam = 0x0D Then ;0x0D = Enter
    MsgBox(0, "", "Enter wurde losgelassen.")
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func WM_KEYDOWN($hWnd, $Msg, $wParam, $lParam)
    If $wParam = 0x0D Then ;0x0D = Enter
    MsgBox(0, "", "Enter wurde gedrückt.")
    EndIf
    Return $GUI_RUNDEFMSG
    EndFunc

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

    Func Event_Close()
    Exit
    EndFunc

    [/autoit]


    Jemand eine Idee woran das liegen könnte?

    2 Mal editiert, zuletzt von mchope57 (4. August 2013 um 01:42)

  • Aber da ist doch kein Edit Control.
    Bei Friesel hat es geklappt, hab auch gegoogelt aber nichts dazu gefunden.

    EDIT: Vllt. kannst du ja mal ausprobieren, ob es bei dir klappt? :)

  • Bei Friesel hat es geklappt, hab auch gegoogelt aber nichts dazu gefunden.


    Also dieses Skript hier funtioniert bei mir auch nicht, Das liegt aber an der Enter-Taste.
    Wenn du zB die Leertaste (0x20) abfragst funktionierts. Allerdings musst du außerdem noch MsgBox durch ConsoleWrite ersetzen, weil die Message Box die Abfrage blockiert.

    Da musst du dir wohl nen Workaround mit HotKeySet oder GUISetAccelerators zusammenklöppeln...

    *edit*
    WM_COMMAND abfangen wäre hier erste Wahl, würde ich sagen...

    [autoit]

    Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    ;ConsoleWrite("|$hWnd: " & $hWnd & " |$Msg: " & $Msg & " |$wParam: " & $wParam & " |$lParam: " & $lParam & @CRLF)
    Switch $wParam
    Case 0
    ConsoleWrite("Enter wurde losgelassen." & @CRLF)
    Case 1
    ConsoleWrite("Enter wurde gedrück." & @CRLF)
    EndSwitch
    Return $GUI_RUNDEFMSG
    EndFunc

    [/autoit]
  • Probiere es mal mit Subclassing:

    [autoit]


    #include <Constants.au3>
    #include <GUIConstants.au3>
    #include <WindowsConstants.au3>
    #include <WinAPI.au3>

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

    Opt("GUIOnEventMode", 1)

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

    $GUI = GUICreate("GUI", 960, 540, Default, Default)
    GUISetState(@SW_SHOW)

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

    $hCallback = DllCallbackRegister("_KeyProc", "long", "int;wparam;lparam")
    $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hCallback), _WinAPI_GetModuleHandle(0))

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

    GUISetOnEvent($GUI_EVENT_CLOSE, "Event_Close")

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

    While 1
    Sleep(100)
    WEnd

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

    Func _KeyProc($nCode, $wParam, $lParam) ;subclassing
    If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    Switch $wparam
    Case $WM_KEYUP
    If DllStructGetData($tKEYHOOKS, "vkCode") = 0x0D Then ConsoleWrite("Enter wurde losgelassen." & @CRLF)
    Case $WM_KEYDOWN
    If DllStructGetData($tKEYHOOKS, "vkCode") = 0x0D Then ConsoleWrite("Enter wurde gedrückt." & @CRLF)
    EndSwitch
    Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndFunc

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

    Func Event_Close()
    _WinAPI_UnhookWindowsHookEx($hHook)
    DllCallbackFree($hCallback)
    GUIDelete()
    Exit
    EndFunc

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    • Offizieller Beitrag

    Man sollte also am Anfang der Funktion _KeyProc noch den Status des Programmfensters abfragen.


    Ja, aber bitte nicht nur Return, dann geht die Msg verloren. Wenn du den Hook auswertest, musst du ihn auf jeden Fall an das System weiterreichen, wenn die Msg nicht verfallen soll:

    [autoit]

    If Not WinActive($GUI) Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)

    [/autoit]