Page 1 sur 1

Aide concernant le test d'un script utilisant le drag and drop

Posté : lun. 16 sept. 2019 14:00
par toto1515
Bonjour,
j'écris un script pour récupérer une liste de fichiers en utilisant un drag and drop depuis l'explorateur vers une listview.

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=EMTEC.ico
#AutoIt3Wrapper_Outfile_x64=Test_copy_move_01.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Run_AU3Check=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

global $debug=0

OnAutoItExitRegister('OnAutoItExit')
Opt("mustdeclarevars", 1)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <GuiListView.au3>

Global $monstring = "", $mList, $total_size = 0, $aFileList, $aFileList_f, $aDrop_List, $dest_folder, $rep_deb

Global $hGUI = GUICreate("File copy/move", 920, 300, -1, 70, Default, $WS_EX_ACCEPTFILES)
GUISetBkColor(0x00E0FFFF) ; will change background color

Global $clist = _GUICtrlListView_Create($hGUI, "", 10, 10, 900, 190)
_GUICtrlListView_SetExtendedListViewStyle($clist, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT))
_GUICtrlListView_InsertColumn($clist, 0, "Origin", 415)
_GUICtrlListView_InsertColumn($clist, 1, "Size", 70)
_GUICtrlListView_InsertColumn($clist, 2, "Destination", 415)
Global $g_clist = GUICtrlGetHandle($clist)


GUICtrlCreatelabel("Drop dest folder there -->", 10, 235, 118, 20);, BitOR(0x0800, 0x0001))
Global $idLabel=GUICtrlCreateinput("",130,210,300,70,bitor(0x0800,0x0001))
GUICtrlSetBkColor(-1,0x00E0F0FF)
Global $g_hLabel = GUICtrlGetHandle($idLabel)

Global $g_hDll = DllCallbackRegister('_WinProc1', 'ptr', 'hwnd;uint;wparam;lparam')

Global $g_pDll = DllCallbackGetPtr($g_hDll)
Global $g_hProc = _WinAPI_SetWindowLong($g_hLabel, $GWL_WNDPROC, $g_pDll)
_WinAPI_DragAcceptFiles($g_hLabel, True)

Global $g_hDll_list = DllCallbackRegister('_WinProclist', 'ptr', 'hwnd;uint;wparam;lparam')
Global $g_pDll_list = DllCallbackGetPtr($g_hDll_list)
Global $g_hProc_list = _WinAPI_SetWindowLong($clist, $GWL_WNDPROC, $g_pDll_list)
_WinAPI_DragAcceptFiles($clist, True)


GUISetState(@SW_SHOW)
While 1
   Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
         Exit
   EndSwitch
WEnd

Func _WinProc1($hWnd, $iMsg, $wParam, $lParam)
   Switch $iMsg
      Case $WM_DROPFILES
         ;on liste les fichiers lors du drop
         Local $aFileList_f = _WinAPI_DragQueryFileEx($wParam, 2)
         If Not @error Then
            if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & '--------------------------------------------------' & @CRLF)
            For $i = 1 To $aFileList_f[0]
               if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$aFileFist_f[" & $i & "]" & $aFileList_f[$i] & @CRLF)
            Next
         Else
            MsgBox(0, "Erreur", "Vous n'avez pas sélectionné un répertoire")
            Return
         EndIf
         If $aFileList_f[0] > 1 Then
            MsgBox(0, "Erreur", "Vous avez sélectionné plusieurs répertoires")
            Return
         EndIf

         GUICtrlSetData($idLabel, $aFileList_f[1])
         $dest_folder = $aFileList_f[1] & "\"

         _WinAPI_DragFinish($wParam)
         ; on met à jour la iste
         maj_liste()
         Return 0
   EndSwitch
   Return _WinAPI_CallWindowProc($g_hProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>_WinProc1

Func _WinProclist($hWnd_l, $iMsg_l, $wParam_l, $lParam_l)
   ;consolewrite("here" & @crlf)

   Switch $iMsg_l
      Case $WM_DROPFILES
         ;on liste les fichiers lors du drop
         $rep_deb = ""
         $aFileList = _WinAPI_DragQueryFileEx($wParam_l, 0)
         If Not @error Then
            For $i = 1 To $aFileList[0]
               if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$aFileList[$i]=" & $aFileList[$i] & @CRLF)
            Next
            $rep_deb = StringLeft($aFileList[1], StringInStr($aFileList[1], "\", 0, -1))
         EndIf
         if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$rep_deb=" & $rep_deb & @CRLF)
         _update_list()
         _WinAPI_DragFinish($wParam_l)
         if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$total_size=" & ByteSuffix($total_size) & @CRLF)
         Return 0
   EndSwitch
   Return _WinAPI_CallWindowProc($g_hProc_list, $hWnd_l, $iMsg_l, $wParam_l, $lParam_l)
EndFunc   ;==>_WinProclist

Func OnAutoItExit()
   _WinAPI_SetWindowLong($g_hLabel, $GWL_WNDPROC, $g_hProc)
   DllCallbackFree($g_hDll)
   _WinAPI_SetWindowLong($clist, $GWL_WNDPROC, $g_hProc_list)
   DllCallbackFree($g_hDll_list)
EndFunc   ;==>OnAutoItExit



Func maj_liste()
   Local $nbitem = _GUICtrlListView_GetItemCount($clist)
   if $debug=1 then MsgBox(0, "Information", "Item Count: " & $nbitem)
   For $i = 0 To $nbitem - 1
      Local $le_texte = _GUICtrlListView_GetItemText($clist, $i)
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$le_texte=" & $le_texte & @CRLF)
      _GUICtrlListView_SetItemText($clist, $i, $dest_folder & StringReplace($le_texte, $rep_deb, ""), 2)
   Next
EndFunc   ;==>maj_liste

Func _update_list()
   $monstring = ""
   $aDrop_List = $aFileList
   Local $destfile
   if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$dest_folder=" & $dest_folder & @CRLF)
   if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$rep_deb=" & $rep_deb & @CRLF)
   Dim $mList[1000][2] = [[0]] ;[FileName][FileSz]
   _GUICtrlListView_DeleteAllItems($clist)
   _GUICtrlListView_BeginUpdate($clist)
   Local $t = 0, $la_taille = 0
   For $i = 1 To $aDrop_List[0]
      _GUICtrlListView_AddItem($clist, $aDrop_List[$i])
      Local $la_taille_octets = FileGetSize($aDrop_List[$i])
      If $la_taille_octets = 0 Then
         $la_taille = ""
      Else
         $la_taille = ByteSuffix($la_taille_octets)
      EndIf
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$la_taille= " & $la_taille & @CRLF)
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$aDrop_List[$i]=" & $aDrop_List[$i] & @CRLF)
      Local $oldfile = $aDrop_List[$i]
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$oldfile=" & $oldfile & @CRLF)
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$rep_deb=" & $rep_deb & @CRLF)
      $destfile = StringReplace($oldfile, $rep_deb, "")
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$destfile=" & $destfile & @CRLF)
      _GUICtrlListView_AddSubItem($clist, $t, $la_taille, 1)

      If $dest_folder <> "" Then
         _GUICtrlListView_AddSubItem($clist, $t, $dest_folder & $destfile, 2)
      EndIf
      $t += 1
      $total_size += $la_taille_octets
      If StringLen($aDrop_List[$i]) < 4 Then MsgBox(0, "Test", "This Will Take a While Message Etc...")
      Find_AllFiles($aDrop_List[$i], $mList, 100) ;Recursively finds files
   Next
   _GUICtrlListView_EndUpdate($clist)
   if $debug=1 then MsgBox(0, "", "on poursuit")
   _GUICtrlListView_BeginUpdate($clist)
   For $i = 1 To $mList[0][0] ;Dumps found files to listview
      $total_size += $mList[$i][1]
      _GUICtrlListView_AddItem($clist, $mList[$i][0])
      _GUICtrlListView_AddSubItem($clist, $t, ByteSuffix($mList[$i][1]), 1)
      ;if $dest_folder<>"" Then
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$mList[$i][0]=" & $mList[$i][0] & @CRLF)
      Local $destfile = StringReplace($mList[$i][0], $rep_deb, "")
      if $debug=1 then ConsoleWrite(@ScriptLineNumber & ": " & "$destfile=" & $destfile & @CRLF)
      _GUICtrlListView_AddSubItem($clist, $t, $dest_folder & $destfile, 2)
      ;endif

      $t += 1
   Next
   _GUICtrlListView_EndUpdate($clist)
EndFunc   ;==>_update_list


Func Find_AllFiles($sPath, ByRef $aList, $iMaxRecursion, $bRecurse = True)
   Local $tData = DllStructCreate($tagWIN32_FIND_DATA)
   Local $sFile
   If StringRight($sPath, 1) <> "\" Then $sPath &= "\"
   Local $hSearch = _WinAPI_FindFirstFile($sPath & '*', $tData)
   While Not @error
      $sFile = DllStructGetData($tData, 'cFileName')
      Switch $sFile
         Case '.', '..'

         Case Else
            If Not BitAND(DllStructGetData($tData, 'dwFileAttributes'), $FILE_ATTRIBUTE_DIRECTORY) Then
               $aList[0][0] += 1
               If $aList[0][0] > UBound($aList) - 1 Then
                  ReDim $aList[UBound($aList) + 4096][2]
               EndIf
               $aList[$aList[0][0]][0] = $sPath & $sFile ;;$sFile ;if you want full path.. $sPath & "\" & $sFile
               $aList[$aList[0][0]][1] = _WinAPI_MakeQWord(DllStructGetData($tData, 'nFileSizeLow'), DllStructGetData($tData, 'nFileSizeHigh'))
            ElseIf $bRecurse Then
               If $iMaxRecursion > 0 Then
                  Find_AllFiles($sPath & $sFile, $aList, $iMaxRecursion - 1, $bRecurse)
               Else
                  MsgBox(0, "Error", "Max Recursion Exceeded")
               EndIf
            EndIf
      EndSwitch
      _WinAPI_FindNextFile($hSearch, $tData)
   WEnd
   _WinAPI_FindClose($hSearch)
EndFunc   ;==>Find_AllFiles

Func ByteSuffix($iBytes, $idecimale = "")
   Local $iIndex = 0, $laArray = [' octets', ' Ko', ' Mo', ' Go', ' To', ' Po', ' Eo', ' Zo', ' Yo']
   Local $idecArray = [0, 1, 2, 3, 3, 3, 3, 3, 3]
   While $iBytes > 1023
      $iIndex += 1
      $iBytes /= 1024
   WEnd
   If $idecimale = "" Then $idecimale = $idecArray[$iIndex]
   Local $mformat = "%." & $idecimale & "f"
   Local $newval = Round($iBytes, $idecimale)
   Return StringFormat($mformat, $newval) & $laArray[$iIndex]

EndFunc   ;==>ByteSuffix

Lorsque je compile mon script (compilation avec options), ça fonctionne.
Test_copy_move_01.zip
le fichier compilé
(772.89 Kio) Téléchargé 110 fois
Image capture 23.jpg

Mais, si je lance la commande exécuter (F5) dans scite, le drag and drop ne fonctionne pas. Je ne peux donc pas tester mon script via Scite.

Quelqu'un pourrait-il m'aider pour pouvoir tester mon script dans Scite? Je dois à chaque fois passer par la compilation pour le tester, ce qui est très pénible.

Merci aux experts

Re: Aide concernant le test d'un script utilisant le drag and drop

Posté : mar. 17 sept. 2019 15:18
par mimione
Bonjour

Je n'ai pas de différence de comportement entre le compilé et l'exécuté dans SCITE...
On parle bien du drag & drop d'un répertoire sur la listview ..?

Re: Aide concernant le test d'un script utilisant le drag and drop

Posté : mar. 17 sept. 2019 17:52
par toto1515
Boujour,
oui, que ce soit sur la listview ou sur l'input, ça ne fonctionne pas.

Pour info, avec le script suivant, que j'ai trouvé sur le forum, j'ai le même soucis :
#cs ----------------------------------------------------------------------------
 AutoIt Version : 3.3.14.5
 Auteur:         François
 Fonction du Script :
   Modèle de Script AutoIt.
#ce ----------------------------------------------------------------------------

#include <GUIConstantsEx.au3> ; $GUI_EVENT_CLOSE
#include <WindowsConstants.au3>
#include <GuiListBox.au3>

#include <WinAPISys.au3> ;WinAPI_ChangeWindowMessageFilterEx ;_WinAPI_DragQueryFileEx
#include <WinAPIFiles.au3> ;_WinAPI_FindFirstFile

$hGUI = GUICreate("FileDrop", 550, 300, Default, Default, Default, $WS_EX_ACCEPTFILES)

$cList = GUICtrlCreateList("", 0, 0, 450, 300)
$labelnb=GUICtrlCreateLabel("",460,280,80,24)
$bClear = GUICtrlCreateButton("Clear", 460, 0, 75, 25)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")

$cDrop_Dummy = GUICtrlCreateDummy() ;Dummy control recieves notifications on filedrop
GUISetState(@SW_SHOW)

If IsAdmin() Then ; Allow WM_DROPFILES to be received from lower privileged processes (Windows Vista or later)
    _WinAPI_ChangeWindowMessageFilterEx($hGUI, $WM_COPYGLOBALDATA, $MSGFLT_ALLOW)
    _WinAPI_ChangeWindowMessageFilterEx($hGUI, $WM_DROPFILES, $MSGFLT_ALLOW)
EndIf

; Register $WM_DROPFILES function to detect drops anywhere on the GUI
GUIRegisterMsg($WM_DROPFILES, "_WM_DROPFILES")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cDrop_Dummy
            _On_Drop(GUICtrlRead($cDrop_Dummy))

        Case $bClear
            GUICtrlSetData($cList, "")
    EndSwitch
WEnd

Func _On_Drop($hDrop)
    Local $aDrop_List = _WinAPI_DragQueryFileEx($hDrop, 0) ; 0 = Returns files and folders
    Local $aList[1000][2] = [[0]] ;[FileName][FileSz]

    For $i = 1 To $aDrop_List[0]
        GUICtrlSetData($cList, $aDrop_List[$i]) ;Dumps dropped files to listview
        IF StringLen($aDrop_List[$i]) < 4 Then MsgBox(0,"Test", "This Will Take a While Message Etc...")
        Find_AllFiles($aDrop_List[$i], $aList, 100) ;Recursively finds files
    Next
    _GUICtrlListBox_BeginUpdate ($cList)
    For $i = 1 To $aList[0][0] ;Dumps found files to listview
        GUICtrlSetData($cList, $aList[$i][0])
    Next
    _GUICtrlListBox_EndUpdate ($cList)
   GUICtrlSetData($labelnb,$aList[0][0])
EndFunc   ;==>_On_Drop


; React to items dropped on the GUI
Func _WM_DROPFILES($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $lParam
    GUICtrlSendToDummy($cDrop_Dummy, $wParam) ;Send the wParam data to the dummy control
EndFunc   ;==>_WM_DROPFILES

Func Find_AllFiles($sPath, ByRef $aList, $iMaxRecursion, $bRecurse = True)

    Local $tData = DllStructCreate($tagWIN32_FIND_DATA)

    Local $sFile
    If StringRight($sPath, 1) <> "\" Then $sPath &= "\"
    Local $hSearch = _WinAPI_FindFirstFile($sPath & '*', $tData)
    While Not @error
        $sFile = DllStructGetData($tData, 'cFileName')
        Switch $sFile
            Case '.', '..'

            Case Else
                If Not BitAND(DllStructGetData($tData, 'dwFileAttributes'), $FILE_ATTRIBUTE_DIRECTORY) Then
                    $aList[0][0] += 1
                    If $aList[0][0] > UBound($aList) - 1 Then
                        ReDim $aList[UBound($aList) + 4096][2]
                    EndIf
                    $aList[$aList[0][0]][0] = $sPath & $sFile;;$sFile ;if you want full path.. $sPath & "\" & $sFile
                    $aList[$aList[0][0]][1] = _WinAPI_MakeQWord(DllStructGetData($tData, 'nFileSizeLow'), DllStructGetData($tData, 'nFileSizeHigh'))
                Elseif $bRecurse Then
                    if $iMaxRecursion > 0 Then
                    Find_AllFiles($sPath & $sFile, $aList, $iMaxRecursion - 1, $bRecurse)
                    Else
                        Msgbox(0,"Error", "Max Recursion Exceeded")
                    EndIF
                EndIf
        EndSwitch
        _WinAPI_FindNextFile($hSearch, $tData)
    WEnd
    _WinAPI_FindClose($hSearch)
EndFunc   ;==>Find_AllFiles
 

Si je lance le script via la touche F5, la console me donne :
>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "G:\dernières récup usb\Autoit\test drag files folder\test 01-.au3" /UserParams    
+>17:41:26 Starting AutoIt3Wrapper v.18.708.1148.0 SciTE v.4.1.0.0   Keyboard:0000040C  OS:WIN_8/  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:0  utf8.auto.check:4
+>         SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE   UserDir => C:\Users\François\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\François\AppData\Local\AutoIt v3\SciTE
>Running AU3Check (3.3.14.5)  from:C:\Program Files (x86)\AutoIt3  input:G:\dernières récup usb\Autoit\test drag files folder\test 01-.au3
+>17:41:26 AU3Check ended.rc:0
>Running:(3.3.14.5):C:\Program Files (x86)\AutoIt3\autoit3_x64.exe "G:\dernières récup usb\Autoit\test drag files folder\test 01-.au3"    
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
"G:\dernières récup usb\Autoit\test drag files folder\test 01-.au3" (54) : ==> Subscript used on non-accessible variable.:
For $i = 1 To $aDrop_List[0]
For $i = 1 To $aDrop_List^ ERROR
->17:41:48 AutoIt3.exe ended.rc:1
+>17:41:48 AutoIt3Wrapper Finished.
>Exit code: 1    Time: 23.43
Si je compile le script via clic droit sur le fichier puis , compile le script (x86), ça fonctionne.
Si je compile le script via clic droit sur le fichier puis , compile le script (x64), ça ne fonctionne pas????

Serait-ce lié à l'architecture de windows 8 x64?
La touche F5, lancerait la compilation en x64?

Je suis un peu perdu...

Re: Aide concernant le test d'un script utilisant le drag and drop

Posté : mar. 17 sept. 2019 18:16
par TommyDDR
Ça doit être parce que SciTE n'est pas lancé avec les droits administrateurs (essayez de le lancer avec clic droit / exécuter en tant qu'administrateur)

Quand vous faites des programmes qui ont des interactions avec les programmes externes au votre, prenez l'habitude de rajouter en début de script :
Et pensez à lancer SciTE en tant qu'administrateur (sinon vous n'aurez pas les logs dans SciTE)

Re: Aide concernant le test d'un script utilisant le drag and drop

Posté : mar. 17 sept. 2019 21:08
par toto1515
Bonsoir,
pour Scite, j'avais déjà mis le programme en mode compatibilité administrateur pour tout le monde.
Suite à votre conseil, j'ai mis #RequireAdmin dans mon script, ça ne fonctionne toujours pas.
J'ai lancé Scite (clic droit: exécuter en tant qu'administrateur), ça ne fonctionne toujours pas.

Tous les exécutables sont en mode administrateur (Autoit3.exe, AutoIt3_x64.exe, AutoIt3Help.exe, Au3Info.exe, Au3Info_x64.exe, Au3Check.exe, SciTE.exe)

J'ai un peu regardé ce qu'il se passait dans au3.properties :

# Commands to compile / run your script
command.go.$(au3)="$(SciteDefaultHome)\..\AutoIt3.exe" "$(SciteDefaultHome)\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "$(FilePath)" /UserParams $(1) $(2) $(3) $(4)

puis dans autoitwrapper et j'ai vu que la touche F5 lançait la commande (ligne 1327)
; Run your script
$Pid = Run('"' & $AutoIt3_PGM & '" /ErrorStdOut "' & $ScriptFile_In & '" ' & $s_CMDLine, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

J'ai donc testé de lancer mon script en glissant le fichier sur Autoit3.exe, il fonctionne.
En le glissant sur Autoit3_64.exe, ça plante.

en fouillant dans Autoitwrapper, ligne 66, il y a :
If @OSArch = "X86" Or StringInStr(RegRead("HKCR\AutoIt3Script\Shell\Run\Command", ""), "AutoIt3.exe") Then
SetDefaults($INP_UseX64, "n", "auto=a;yes=y;no=n;1=y;0=n;4=n", "y;n", 0, 0)
Else
SetDefaults($INP_UseX64, "y", "auto=a;yes=y;no=n;1=y;0=n;4=n", "y;n", 0, 0)
EndIf
Or, la clef "HKCR\AutoIt3Script\Shell\Run\Command" n'existe pas dans ma base de registre, il y a "HKCR\AutoIt3Script\Shell\RunX86\Command" et
"HKCR\AutoIt3Script\Shell\RunX64\Command", ce qui implique que la variable $INP_UseX64 soit mise à "y" et par corolaire que $AutoIt3_PGM soit autoit3_x64.exe. Or avec autoit3_x64.exe ça plante.

Je viens de tester en modifiant la ligne :
If @OSArch = "X86" Or StringInStr(RegRead("HKCR\AutoIt3Script\Shell\Run\Command", ""), "AutoIt3.exe")
par
If @OSArch = "X86" Or StringInStr(RegRead("HKCR\AutoIt3Script\Shell\RunX86\Command", ""), "AutoIt3.exe")
et , le lancement du 2ème script dans Scite par la touche F5 fonctionne maintenant.
Par contre, avec le premier script, ça ne marche pas.

Ce qui me perturbe, c'est que le compilation des scripts (compile avec options) fonctionne.

Peut-être est-il préférable que je désinstalle complètement Autoit et que je le réinstalle ?
Qu'en pensez-vous ?

[R] Aide concernant le test d'un script utilisant le drag and drop  

Posté : sam. 21 sept. 2019 18:01
par toto1515
Bonjour,
j'ai résolu mon problème :

- désinstallation de AUtoit, de Scite, .....
- Suppression des clef de la base de registre ayant un lien avec autoit.

et finalement installation du dernier pack autoit fr.

Tout fonctionne maintenant.