Drag & Drop überprüfen

  • Hallo

    nach langer Zeit hab ich mal wieder eine Frage.

    Folgendes Senario:
    Ich habe ein Inputfeld das per Drag and Drop Datei(en) akzeptiert und den Pfad in dem Inputfeld einträgt. Das Funktioniert auch ohne Probleme mit einer und mehreren Dateien.
    ´
    Mein Problem: Wenn der Cursor (der blinkende Strich für die Zeicheneingabe :D ) sich irgendwo in dem Inputfeld befindet (auch in mitten eines Pfades), wird der neue, per DnD eingefügte, Dateipfad an dem Cursor eingefügt und somit zwischen einen anderen Pfad oder an falscher Stelle eingefügt.

    Meine Frage: Wie kann ich dieses Problem umgehen. Oder besser wäre eine Möglichkeit zum Kontrollieren ob eine Datei per DnD auf das Feld gezogen wurde. Ich komme einfach nicht weiter. :(
    Hab schon verchiedene Sachen probiert mit ControlDisable und dem Style $ES_READONLY.
    Code ist nix weiter außer eben das Inputfel und GUI mit Dropaccept. Nicht mehr und nicht weniger.

    Wie immer bin ich sehr dankbar für eure gute und schnelle Hilfe.
    Gruß

    • Offizieller Beitrag

    Wenn ich das richtig verstanden habe, dann willst du, das der Filenamen in die Input eingefügt wird und der alte Inhalt überschrieben wird.
    So sollte es klappen:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <GUIConstantsEx.au3>

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

    Opt('MustDeclareVars', 1)
    Global $WM_DROPFILES = 0x233
    Global $file, $btn, $msg
    Example()

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

    Func Example()

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

    GUICreate(" My GUI input acceptfile", 320, 120, @DesktopWidth / 2 - 160, @DesktopHeight / 2 - 45, -1, 0x00000018); WS_EX_ACCEPTFILES
    $file = GUICtrlCreateInput("", 10, 5, 300, 20)
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)
    $btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)

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

    GUISetState()
    GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES")
    $msg = 0
    While $msg <> $GUI_EVENT_CLOSE
    $msg = GUIGetMsg()
    Select
    Case $msg = $btn
    ExitLoop
    EndSelect
    WEnd

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

    MsgBox(4096, "drag drop file", GUICtrlRead($file))
    EndFunc ;==>Example

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

    Func WM_DROPFILES($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255); Files aus dem Query laden
    $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0, "ptr", 0, "int", 0); Größe Filenemes des 1. Eintrages
    $nSize = $nSize[0] + 1
    $pFileName = DllStructCreate("char[" & $nSize & "]")
    DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0, "ptr", DllStructGetPtr($pFileName), "int", $nSize);1. Filenamen holen
    GUICtrlSetData($file, DllStructGetData($pFileName, 1));Daten in Input schreiben, der alte Inhalt wird überschrieben
    Return 1; Message als erledigt deklarieren sonst wird der Filenamen 2 mal eingefügt
    EndFunc ;==>WM_DROPFILES

    [/autoit]

    Edit:
    Hier noch eine Minimalversion:

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    #include <GUIConstantsEx.au3>

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

    Opt('MustDeclareVars', 1)
    Global $WM_DROPFILES = 0x233
    Global $file, $btn, $msg
    Example()

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

    Func Example()

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

    GUICreate(" My GUI input acceptfile", 320, 120, @DesktopWidth / 2 - 160, @DesktopHeight / 2 - 45, -1, 0x00000018); WS_EX_ACCEPTFILES
    $file = GUICtrlCreateInput("", 10, 5, 300, 20)
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)
    $btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)

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

    GUISetState()
    GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES")
    $msg = 0
    While $msg <> $GUI_EVENT_CLOSE
    $msg = GUIGetMsg()
    Select
    Case $msg = $btn
    ExitLoop
    EndSelect
    WEnd

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

    MsgBox(4096, "drag drop file", GUICtrlRead($file))
    EndFunc ;==>Example

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

    Func WM_DROPFILES($hWnd, $msgID, $wParam, $lParam)
    GUICtrlSetData($file, "")
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_DROPFILES

    [/autoit]
  • So ... Mittag ist verspeißt ... jetzt folgt der Code.

    Spoiler anzeigen
    [autoit]

    #Include <Array.au3>
    #include <Process.au3>
    #include <GUIConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <DateTimeConstants.au3>
    #Include <Date.au3>

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

    Opt("GUIOnEventMode",1)

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

    $GUI = GUICreate("Beispiel",280,100,-1,-1,-1,0x00000018)
    GUISetOnEvent(-3,"_Exit")
    $Input = GUICtrlCreateInput("...",10,10,220,20)
    GuiCtrlSetState(-1,$GUI_DROPACCEPTED)
    GUICtrlCreateButton("...",240,10,30,20)
    ;~ GUICtrlSetOnEvent(-1,"_Pfad")
    $Datum = GUICtrlCreateDate("",10,40,80,20,$DTS_SHORTDATEFORMAT)
    $Zeit = GUICtrlCreateDate("", 100, 40, 80, 20, $DTS_TIMEFORMAT)
    GUICtrlCreateButton("Datum ändern",10,70,80,20)
    ;~ GUICtrlSetOnEvent(-1,"_OK")
    GUICtrlCreateButton("Beenden",100,70,80,20)
    GUICtrlSetOnEvent(-1,"_Exit")
    GUISetState(@SW_SHOW,$GUI)

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

    while 1
    $InputDnD = StringSplit(GUICtrlRead($Input),"|")
    If $InputDnD[0] > 1 then
    For $DnD = 1 to $InputDnD[0]
    GUICtrlSetData($Input,'"'&$InputDnD[$DnD]&'" ',GUICtrlRead($Input))
    Next
    $InputDnD[0] = 1
    EndIf
    WEnd

    func _Exit()
    Exit
    EndFunc

    [/autoit]

    Wie es dann in der Inputbox eingefügt wird (mit den ") hängt mit dem nachher kommenden aufrufen der Dateien zusammen. Problem wie oben beschrieben.
    Eine Datei per Drag&Drop in die Inputbox ziehen. Dann in die Inputbox klicken, so das der Cursor blinkt. Erneut eine Datei via Drag&Drop in das Inputfeld ziehen.

    Ergebnis: Der neue Pfad wird an dem Cursor eingefügt, der alte aber vorher nicht gelöscht. Und genau das soll behoben werden. :)

    Edit: Danke Raupi, aber das ist ja im GetMsg Modus. Ich arbeite vorwiegend im OnEvent Modus. Wenn es nicht anders gehen sollte bau ich halt auf GetMsg um. :P

    Einmal editiert, zuletzt von Prixma (17. März 2011 um 12:08)

    • Offizieller Beitrag

    Der Modus ist doch egal. Funzt auch im OnEventMode.

  • Wenn du immer nur eine Datei annehmen willst, dann reichen die Standardfunktionen völlig aus:

    Spoiler anzeigen
    [autoit]

    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <GUIEdit.au3>

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

    Opt("GUIOnEventMode", 1)

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

    GUICreate(" My GUI input acceptfile", 320, 120, @DesktopWidth / 2 - 160, @DesktopHeight / 2 - 45, Default, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
    $file = GUICtrlCreateInput("", 10, 5, 300, 20)
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)
    $btn = GUICtrlCreateButton("Ok", 40, 75, 60, 20)
    GUICtrlSetOnEvent(-1, "_OK")
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetOnEvent($GUI_EVENT_DROPPED, "_Dropped")
    GUISetState()

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

    While 1
    Sleep(1000)
    WEnd

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

    Func _OK()
    $data = GUICtrlRead($file)
    GUIDelete()
    MsgBox(0, '', $data)
    Exit
    EndFunc
    Func _Dropped()
    If @GUI_DropId = $file Then
    GUICtrlSetData($file, @GUI_DragFile)
    _GUICtrlEdit_SetSel($file, 0, -1)
    EndIf
    EndFunc
    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    WM_DROPFILES braucht man erst, wenn man z.B. auf der ganzen GUI ohne bestimmtes Control Dateien annehmen will oder man mehrere Dateien auf einmal ablegen können soll.

    • Offizieller Beitrag

    Ups, hab doch glatt vergessen das es $GUI_EVENT_DROPPED gibt :sleeping:

  • Hi

    Eigentlich wollte ich es so machen, das es auch mit mehreren Dateien geht.
    Ich werde mich mal an euren Vorschlägen probieren.