Focus auf anderes Control funktioniert, aber Text Cursor immer noch im alten Control

  • Hi,
    ich habe ein Edit Control mit _GUICtrlEdit_Create erstellt und als parent handle gebe ich das handle eines ListViews an. Dadurch sendet das Control keine Message codes mehr, aber ich habe einen anderen Weg gefunden einen Klick in dieses Edit Control abzufangen. Beim klicken in das Edit Control öffnen sich ein FileOpen Dialog und fügt den Pfad in das Control ein. Das Problem ist das ein weiterer Klick, die Funktion wieder aufruft, da der Fokus bzw. der Text Cursor immer noch auf dem Control liegt. Wenn ich den Fokus ändere

    [autoit]

    ConsoleWrite("state: " & ControlFocus("", "", 33) & @CRLF)

    [/autoit]


    und den aktuellen Fokus abfrage

    [autoit]

    GUICtrlSetState(33, $GUI_FOCUS)

    [/autoit]

    liegt der fokus auf dem neuen control, aber der Text Cursor ist nach wie vor im alten Control und damit wird auch beim Klick egal wohin, wieder die FileOpen Funktion aufgerufen.

    Habe echt schon alles durch, hat jemand eine Idee? ?(

  • haha Danke BugFix, als ich gerade meinen Test Code Schnipsel für dich zurecht basteln wollte, habe ich erst bemerkt, das es dort bereits funktioniert. Ein einfaches Return 0 hat schon ausgereicht. Ich häng den Code mal mit dran Jung.

    [autoit]


    #include <GuiConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <Constants.au3>
    #include <WinAPI.au3>
    #include <GuiEdit.au3>
    #include <GuiListView.au3>
    $wProcHandle = DllCallbackRegister("_WindowProc", "ptr", "hwnd;uint;wparam;lparam")

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

    $hGUI = GUICreate("Test GUI", 300, 300)
    $hListView = _GUICtrlListView_Create($hGUI, "", 2,2, 250, 250)

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

    $hEdit = _GUICtrlEdit_Create($hListView, "This is a test" & @CRLF & "Another Line", 20, 20, 150, 50,BitOR($WS_TABSTOP, $WS_CHILD, $WS_VISIBLE, $ES_LEFT, $ES_AUTOHSCROLL, $ES_NOHIDESEL), $WS_EX_CLIENTEDGE)
    $hEdit2 = _GUICtrlEdit_Create($hListView, "This is a test2" & @CRLF & "Another Line", 20, 80, 100, 50,BitOR($WS_TABSTOP, $WS_CHILD, $WS_VISIBLE, $ES_LEFT, $ES_AUTOHSCROLL, $ES_NOHIDESEL), $WS_EX_CLIENTEDGE)
    ;~ Local $test = $hEdit
    ConsoleWrite("ret: " & Hex(_WinAPI_GetWindowLong ( $hEdit, $GWL_WNDPROC )) & @CRLF)

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

    ;~ ConsoleWrite("state: " & ControlDisable ($hGUI, "", _WinAPI_GetDlgCtrlID($hEdit2)) & @CRLF)

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

    $wProcOld = _WinAPI_SetWindowLong($hEdit, $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))
    $wProcOld2 = _WinAPI_SetWindowLong($hEdit2, $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))
    ConsoleWrite("$wProcOld: " & Hex($wProcOld) & " $wProcOld2: " &Hex($wProcOld2) & " $wProcHandle: " & $wProcHandle & " $hGUI: " & $hGUI & " $hListView: " & $hListView & " $hEdit: " & $hEdit & @CRLF)
    GUISetState()

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

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

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

    GUIDelete($hGui)
    DllCallbackFree($wProcHandle)

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

    Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    If $Msg = $WM_LBUTTONDOWN Then
    ConsoleWrite("-> Left mouse click" & @LF)
    Local $sFileOpenDialog = FileOpenDialog("Titel", @WindowsDir & "", "All (*.*)", $FD_FILEMUSTEXIST)
    _GUICtrlEdit_SetText($hWnd, $sFileOpenDialog)
    Return 0
    EndIf
    Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $Msg, $wParam, $lParam )
    EndFunc

    [/autoit]

    Da ist noch eine Sache, die ich nicht verstehe: Ich muss Return _WinAPI_CallWindowProc($wProcOld, $hWnd, $Msg, $wParam, $lParam ) aufrufen, da sonst die Edit controls nicht angezeigt werden. Ich würde gerne wissen, wieso der Parameter $wProcOld bei Edit Controls immer gleich ist, denn ich habe beiden Edit Controls mit _WinAPI_SetWindowLong mit der Funktion _WindowProc verknüpft und beide geben IMMER 0x743B99D0 zurück. Woher kommt dieser Wert, scheint ja eine Konstante zu sein, aber in den Includes habe ich den Wert nicht gefunden?

    Edit: Habe gerade folgendes zu CallWindowProc in der msdn gefunden:

    Zitat

    The SetWindowLong function creates the subclass by changing the window procedure associated with a particular window, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures.

    Ok, _WindowProc wird also als Zwischen Prozedur aufgerufen und ruft zum Schluss wieder die alte Prozedur auf. Also ist der Wert ein Pointer auf die alte Prozedur oder so ähnlich, wie kommts das es den Wert nicht als feste Konstante gibt, wenn er doch eigentlich Global und immer gleich ist?

    Danke!

    Einmal editiert, zuletzt von Trolleule1337 (7. August 2014 um 14:39)

  • 0x743B99D0 müsste eigentlich die Prozedur in der User32.dll sein wenn ich mich nicht irre.
    Würde man vor dieser Prozedur eine weitere einfügen und die DLL neu kompilieren so dürfte sich der Wert auch ändern.
    Hätte man diesen Wert nun als Konstante dann könnte es einen schwerwiegenen Fehler geben wenn man an der DLL nun irgendetwas ändern würde.

    Kann aber auch sein das ich mich irre.