Sign in to follow this  
Followers 0
Lazycat

Drop multiple files on any control

17 posts in this topic

Yesterday I made some tool that was need to drop multiple files onto it. GUI_DragFile handle only single file, Edit though accept multiple files, was not suitable for me.

Fortunately, with GUIRegisterMsg this become pretty simple.

#include <GUIConstants.au3>

Global $WM_DROPFILES = 0x233
Global $gaDropFiles[1], $str = ""

### Koda GUI section start ###
$hGUI = GUICreate("Test", 400, 200, 219, 178, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
$hList = GUICtrlCreateList("", 5, 5, 390, 190)
GUICtrlSetState (-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)
### Koda GUI section end   ###

GUIRegisterMsg ($WM_DROPFILES, "WM_DROPFILES_FUNC")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_DROPPED
            $str = ""
            For $i = 0 To UBound($gaDropFiles) - 1
               $str &= "|" & $gaDropFiles[$i]
            Next
            GUICtrlSetData($hList, $str)
    EndSwitch
WEnd

Func WM_DROPFILES_FUNC($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0) 
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("char[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $gaDropFiles[$i+1]
        $gaDropFiles[$i] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
EndFunc

MultiDropTest.au3

Share this post


Link to post
Share on other sites



Thank you for this code

But why the list is cleared each time we drop one or more files ?

Can't we add the files at the end of the list if there is more than one drop ?

Share this post


Link to post
Share on other sites

Will that (drop multiple files) work also with a ListView GUI, if I change it a little bit?

br, Reinhard

Share this post


Link to post
Share on other sites

Will that (drop multiple files) work also with a ListView GUI, if I change it a little bit?

br, Reinhard

Works great. For that I was looking for monthes without luck and a LV with a input box under it for multi d&d does not really looks cool.

Thank you very much for the tool/demo.

Best regards, Reinhard

Share this post


Link to post
Share on other sites

Works great. For that I was looking for monthes without luck and a LV with a input box under it for multi d&d does not really looks cool.

Thank you very much for the tool/demo.

Best regards, Reinhard

Hey, so your saying that it works for LV too? Can u pls show us the code you used?

Share this post


Link to post
Share on other sites

Hey, so your saying that it works for LV too? Can u pls show us the code you used?

Here a quick example based on helpfile and the demo code from Lazycat (see above).

Enjoy it, Reinhard

;; Quick example for: Drag&Drop Files on a Listview;;

#include <GUIConstants.au3>
#include <GuiListView.au3>

Global $WM_DROPFILES = 0x233
Global $gaDropFiles[1]

GUICreate("listview items",220,250, 100,200,-1,$WS_EX_ACCEPTFILES)
GUISetBkColor (0x00E0FFFF) ; will change background color

$listview = GUICtrlCreateListView ("Filename                      ",10,10,200,150);,$LVS_SORTDESCENDING)
GUICtrlSetState(-1,$GUI_DROPACCEPTED)  ; to allow drag and dropping
$button = GUICtrlCreateButton ("Value?",75,170,70,20)
$nItem=GUICtrlCreateListViewItem("D&D Files on LV",$listview)
GUISetState()

GUIRegisterMsg ($WM_DROPFILES, "WM_DROPFILES_FUNC")

Do
  $msg = GUIGetMsg ()
    Select
      Case $msg = $button
         MsgBox(0,"listview item",GUICtrlRead(GUICtrlRead($listview)),2)
      Case $msg = $listview
         MsgBox(0,"listview", "clicked="& GUICtrlGetState($listview),2)
      Case $msg = $GUI_EVENT_DROPPED
         _GUICtrlListViewDeleteAllItems($listview)
         For $i = 0 To UBound($gaDropFiles) - 1
            $nItem = GUICtrlCreateListViewItem($gaDropFiles[$i],$listview)
         Next
    EndSelect
Until $msg = $GUI_EVENT_CLOSE

Func WM_DROPFILES_FUNC($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0) 
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("char[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $gaDropFiles[$i+1]
        $gaDropFiles[$i] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
EndFunc

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

hi great script i've done as you suggest to allow multiple files, but what bit makes it an ascending list and not descending??

thanks for any help

ooops sussed it! t'was my fault for not using $LVS_SORTASCENDING

Edited by Rick

Who needs puzzles when we have AutoIt!!

Share this post


Link to post
Share on other sites

nice work! does this work for edit controls.. ? i want to return the file contents via fileread, but it just returns filename everytime.. :">


Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

nice work! does this work for edit controls.. ? i want to return the file contents via fileread, but it just returns filename everytime.. :">

Yes it works on edit controls.

Drop some .txt files into the edit box (can drop any files, but only .txt files will show their contents in this crude example)...

#include <GUIConstants.au3>

Global $WM_DROPFILES = 0x233
Global $gaDropFiles[1]

GUICreate('Drop Edit', 400, 300, -1, -1, -1, $WS_EX_ACCEPTFILES)
$Edit = GUICtrlCreateEdit('', 10, 10, 380, 280)
GUICtrlSetState (3, $GUI_DROPACCEPTED)
GUISetState()

GUIRegisterMsg ($WM_DROPFILES, "WM_DROPFILES_FUNC")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_DROPPED 
            Drop()
    EndSwitch
WEnd    

Func Drop()
    For $i = 0 To UBound($gaDropFiles) - 1
        $sp = StringRight($gaDropFiles[$i], 4)
        If $sp = '.txt' Then
            $fo = FileOpen($gaDropFiles[$i], 0)
            If Not @error Then
                $fr = FileRead($fo)
                If Not @error Then
                    GUICtrlSetData($Edit, 'Contents of: ' & $gaDropFiles[$i] & @CRLF & $fr & @CRLF & @CRLF & GUICtrlRead($Edit))
                    FileClose($fo)
                Else
                    FileClose($fo)
                EndIf
            EndIf   
        EndIf   
    Next
EndFunc

Func WM_DROPFILES_FUNC($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("char[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFile", "hwnd", $wParam, "int", $i, "ptr", DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $gaDropFiles[$i + 1]
        $gaDropFiles[$i] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
EndFunc

Cheers

Edit: Removed double entry..

Edited by smashly

Share this post


Link to post
Share on other sites

Yes it works on edit controls.

Drop some .txt files into the edit box (can drop any files, but only .txt files will show their contents in this crude example)...

thanks..


Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

I use Lazycat's "WM_DROPFILES_FUNC" for a while with no problem but yesterday i've notice a lack in this function:

Files with unicode char in their name aren't supported so i've search the unicode function...

And i've found it: "DragQueryFileW" instead of DragQueryFile or DragQueryFileA for ANSI

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
Global $WM_DROPFILES = 0x233
Global $gaDropFiles[1], $str = ""

### Koda GUI section start ###
$hGUI = GUICreate("Test", 400, 200, 219, 178, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_TOPMOST))
$hList = GUICtrlCreateList("", 5, 5, 390, 190)
GUICtrlSetState (-1, $GUI_DROPACCEPTED)
GUISetState(@SW_SHOW)
### Koda GUI section end   ###

GUIRegisterMsg ($WM_DROPFILES, "WM_DROPFILES_UNICODE_FUNC")

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case $GUI_EVENT_DROPPED
            $str = ""
            For $i = 0 To UBound($gaDropFiles) - 1
               $str &= "|" & $gaDropFiles[$i]
            Next
            GUICtrlSetData($hList, $str)
    EndSwitch
WEnd

Func WM_DROPFILES_UNICODE_FUNC($hWnd, $msgID, $wParam, $lParam)
    Local $nSize, $pFileName
    Local $nAmt = DllCall("shell32.dll", "int", "DragQueryFileW", "hwnd", $wParam, "int", 0xFFFFFFFF, "ptr", 0, "int", 255)
    For $i = 0 To $nAmt[0] - 1
        $nSize = DllCall("shell32.dll", "int", "DragQueryFileW", "hwnd", $wParam, "int", $i, "ptr", 0, "int", 0)
        $nSize = $nSize[0] + 1
        $pFileName = DllStructCreate("wchar[" & $nSize & "]")
        DllCall("shell32.dll", "int", "DragQueryFileW", "hwnd", $wParam, "int", $i, "int", DllStructGetPtr($pFileName), "int", $nSize)
        ReDim $gaDropFiles[$i + 1]
        $gaDropFiles[$i] = DllStructGetData($pFileName, 1)
        $pFileName = 0
    Next
EndFunc   ;==>WM_DROPFILES_UNICODE_FUNC

MultiDropUnicodeTest.au3

Njoy ! :)

Edited by taz742

Share this post


Link to post
Share on other sites

This simple way works for me for edit controls. After you have dragged all the files, deleted some lines or whatever you want, you then can GUICtrlRead it into an array (or whatever).

#include <GUIConstants.au3>
#Include <GuiEdit.au3>

$GUI_WIDTH = 400
$GUI_HEIGHT = 300
GUICreate("", $GUI_WIDTH, $GUI_HEIGHT, -1, -1, -1, $WS_EX_ACCEPTFILES)

$edit = GUICtrlCreateEdit("", 10, 10, 380, 280, $WS_VSCROLL)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)

GUISetState(@SW_SHOW)

While 1
  $msg = GUIGetMsg()
  Select
    Case $msg = $GUI_EVENT_CLOSE
      Exit
    Case $msg = $GUI_EVENT_DROPPED
      _GUICtrlEdit_SetSel($edit,-1,-1)
    Case $msg = $GUI_EVENT_MOUSEMOVE
      $mousePos = GUIGetCursorInfo()
      If ($mousePos[0]<-3 Or $mousePos[0]>$GUI_WIDTH+2 Or _
          $mousePos[1]<0 Or $mousePos[1]>$GUI_HEIGHT+2) Then
        _GUICtrlEdit_SetSel($edit,-1,-1)
      EndIf
  EndSelect
WEnd

Share this post


Link to post
Share on other sites

#15 ·  Posted

WM_DROPFILES_FUNC wrong when filename contains Japanese characters. Ex: BigProjectアドバイスパターン表.xls ---> Function return is BigProject???????.xls

Please help me.

Share this post


Link to post
Share on other sites
WM_DROPFILES_FUNC wrong when filename contains Japanese characters. Ex: BigProjectアドバイスパターン表.xls ---> Function return is BigProject???????.xls

Please help me.

 

Please check tp help me

Share this post


Link to post
Share on other sites

SOLVED :thumbsup:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0