Editfeld - Fehler beim beenden

  • Hi,
    ich habe eine GUI und ein Editfeld mit einem benutzerdefinierten Kontextmenü.
    Wenn ich mit einem Rechtsklick auf das Editfeld die GUI beende, steht in der Konsole

    Zitat

    !>19:03:40 AutoIT3.exe ended.rc:-1073741819

    Weiß einer warum diese Meldung kommt?

    Spoiler anzeigen
    [autoit]

    #region ;************ Includes ************
    #include <Constants.au3>
    #include <WindowsConstants.au3>
    #include <GuiMenu.au3>
    #endregion ;************ Includes ************

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

    Opt("GUIOnEventMode", 1) ; 0=ausgeschaltet, 1=OnEvent Modus aktiviert

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

    GUICreate("Meine GUI")
    Global $idEdit = GUICtrlCreateEdit("", 10, 10)
    Global $idKontext2 = GUICtrlCreateContextMenu()
    Global $idKontext_beenden = GUICtrlCreateMenuitem("Beenden", $idKontext2)

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

    GUISetState(@SW_SHOW)

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

    Global $w_editBoxProcNew = DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;long;ptr")
    Global $w_editBoxProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($idEdit), $GWL_WNDPROC, DllCallbackGetPtr($w_editBoxProcNew))
    _WinAPI_SetWindowLong(GUICtrlGetHandle($idEdit), $GWL_WNDPROC, DllCallbackGetPtr($w_editBoxProcNew))

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

    Func MenuItem($iSelected)
    Switch $iSelected
    Case $idKontext_beenden
    _beenden()
    EndSwitch
    EndFunc ;==>MenuItem

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

    Func _MyWindowProc($hWnd, $uiMsg, $wParam, $lParam)
    Switch $uiMsg
    Case $WM_CONTEXTMENU
    If $hWnd = GUICtrlGetHandle($idEdit) Then
    ; show our context menu
    Local $iSelected = _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($idKontext2), $hWnd, -1, -1, 1, 1, 2)
    MenuItem($iSelected)
    Return 0
    EndIf
    EndSwitch
    ;pass the unhandled messages to default WindowProc
    Return _WinAPI_CallWindowProc($w_editBoxProcOld, $hWnd, $uiMsg, $wParam, $lParam)
    EndFunc ;==>_MyWindowProc

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

    Func _beenden()
    _WinAPI_SetWindowLong(GUICtrlGetHandle($idEdit), $GWL_WNDPROC, $w_editBoxProcOld)
    DllCallbackFree($w_editBoxProcNew) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Absturz beim beenden mit einem Rechtsklick auf das Editfeld >>> wird diese Zeile deaktiviert, kommt kein Fehler, warum???
    Exit
    EndFunc ;==>_beenden

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

    While 1
    Sleep(10)
    WEnd

    [/autoit]
  • Mach es doch dann so:

    Spoiler anzeigen
    [autoit]

    #region ;************ Includes ************
    #include <Constants.au3>
    #include <WindowsConstants.au3>
    #include <GuiMenu.au3>
    #endregion ;************ Includes ************

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

    Opt("GUIOnEventMode", 1) ; 0=ausgeschaltet, 1=OnEvent Modus aktiviert

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

    Global $xDoExit = False

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

    GUICreate("Meine GUI")
    Global $idEdit = GUICtrlCreateEdit("", 10, 10)
    Global $idKontext2 = GUICtrlCreateContextMenu()
    Global $idKontext_beenden = GUICtrlCreateMenuitem("Beenden", $idKontext2)

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

    GUISetState(@SW_SHOW)

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

    Global $w_editBoxProcNew = DllCallbackRegister("_MyWindowProc", "ptr", "hwnd;uint;long;ptr")
    Global $w_editBoxProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($idEdit), $GWL_WNDPROC, DllCallbackGetPtr($w_editBoxProcNew))
    _WinAPI_SetWindowLong(GUICtrlGetHandle($idEdit), $GWL_WNDPROC, DllCallbackGetPtr($w_editBoxProcNew))

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

    While 1
    Sleep(10)
    If $xDoExit Then _beenden()
    WEnd

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

    Func MenuItem($iSelected)
    Switch $iSelected
    Case $idKontext_beenden
    $xDoExit = True
    EndSwitch
    EndFunc ;==>MenuItem

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

    Func _MyWindowProc($hWnd, $uiMsg, $wParam, $lParam)
    Switch $uiMsg
    Case $WM_CONTEXTMENU
    If $hWnd = GUICtrlGetHandle($idEdit) Then
    ; show our context menu
    Local $iSelected = _GUICtrlMenu_TrackPopupMenu(GUICtrlGetHandle($idKontext2), $hWnd, -1, -1, 1, 1, 2)
    MenuItem($iSelected)
    Return 0
    EndIf
    EndSwitch
    ;pass the unhandled messages to default WindowProc
    Return _WinAPI_CallWindowProc($w_editBoxProcOld, $hWnd, $uiMsg, $wParam, $lParam)
    EndFunc ;==>_MyWindowProc

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

    Func _beenden()
    _WinAPI_SetWindowLong(GUICtrlGetHandle($idEdit), $GWL_WNDPROC, DllCallbackGetPtr($w_editBoxProcOld))
    DllCallbackFree($w_editBoxProcNew) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Absturz beim beenden mit einem Rechtsklick auf das Editfeld >>> wird diese Zeile deaktiviert, kommt kein Fehler, warum???
    Exit
    EndFunc ;==>_beenden

    [/autoit]
  • Genau. Das Problem ist, wenn _MyWindowProc aufgerufen wird, erwartet Windows das die Funktion beendet wird und einen Rückgabewert abliefert. Da du aber dann in eine Funktion springst und dann in die nächste und sofort beendest und denn Callback wieder freigibst und dadurch MyWindowProc killst, crasht die Anwendung und Windows kann das Programm nicht beenden.
    Ich hoffe es ist so richtig, wenn nicht soll es bitte ein Experte berichtigen. :D