1

Тема: AHK (HelpToAHK_L): ShellFileOperation

По Ctrl+Q должен копировать выбранный файл на Рабочий.


#SingleInstance force

TargetDir = %A_Desktop%\

^vk51::                                      ;Ctrl+Q
   clipboard =
   SendInput, {Ctrl Down}{vk43}{Ctrl Up}     ;Ctrl+C
   ClipWait

   GlobalFileList = %clipboard%

   flags := ( FOF_NOCONFIRMMKDIR := 0x200 ) | (FOF_NOCONFIRMATION := 0x10)
   Loop, parse, GlobalFileList, `r`n
   {
      if (A_LoopField <> "")
      {
         ;MsgBox, Source %A_LoopField%, Target is %TargetDir%
         ShellFileOperation(0x2, A_LoopField, TargetDir, flags)
      }
   }
Return

ShellFileOperation( fileO=0x0, fSource="", fTarget="", flags=0x0, ghwnd=0x0 )     
{
 If ( SubStr(fSource,0) != "|" )
      fSource := fSource . "|"

 If ( SubStr(fTarget,0) != "|" )
      fTarget := fTarget . "|"

 fsPtr := &fSource
 Loop, % StrLen(fSource)
  If ( *(fsPtr+(A_Index-1)) = 124 ) 
      DllCall( "RtlFillMemory", UInt, fsPtr+(A_Index-1), Int,1, UChar,0 ) 

 ftPtr := &fTarget
 Loop, % StrLen(fTarget)
  If ( *(ftPtr+(A_Index-1)) = 124 ) 
      DllCall( "RtlFillMemory", UInt, ftPtr+(A_Index-1), Int,1, UChar,0 ) 

 VarSetCapacity( SHFILEOPSTRUCT, 30, 0 )                 ; Encoding SHFILEOPSTRUCT
 NextOffset := NumPut( ghwnd, &SHFILEOPSTRUCT )          ; hWnd of calling GUI
 NextOffset := NumPut( fileO, NextOffset+0    )          ; File operation
 NextOffset := NumPut( fsPtr, NextOffset+0    )          ; Source file / pattern
 NextOffset := NumPut( ftPtr, NextOffset+0    )          ; Target file / folder
 NextOffset := NumPut( flags, NextOffset+0, 0, "Short" ) ; options

 DllCall( "Shell32\SHFileOperationA", UInt,&SHFILEOPSTRUCT )
 
Return NumGet( NextOffset+0 )
}

2

Re: AHK (HelpToAHK_L): ShellFileOperation

DD пишет:

По Ctrl+Q должен копировать выбранный файл на Рабочий.

Должен, но не копирует. Windows 7.

Потом, если уж используешь для копирования "продвинутый" DllCall(), то моветон получать выделенные файлы примитивным посылом Ctrl+C.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK (HelpToAHK_L): ShellFileOperation

Как раз забыл добавить вопрос: как оный DllCall() заставить копировать, на AHK_L он не работает.
По поводу посыла Ctrl+C согласен, использовал как пример, для удобства и краткости.

4

Re: AHK (HelpToAHK_L): ShellFileOperation

^vk51::
    Clipboard := ""
    SendInput, {Ctrl Down}{vk43}{Ctrl Up}
    ClipWait

    loop parse, Clipboard, `n, `r
    {
        Splitpath A_LoopField, name
        dest := A_Desktop "\" name

        if InStr(FileExist(A_LoopField), "D")
            FileCopyDir % A_LoopField, % dest
        else FileCopy % A_LoopField, % dest
    }
Return

Использование DllCall делает решение любой задачи внушительнее.

5

Re: AHK (HelpToAHK_L): ShellFileOperation

creature.ws, спасибо. Но хотелось бы приноровить первоначальный код к AHK_L, потому что при копировании там можно задействовать целый ряд возможностей (переменная "flags"). Кроме того на нём основывается скрипт, который пытаюсь "оживить".

6

Re: AHK (HelpToAHK_L): ShellFileOperation

Эврика:

ShellFileOperation( fileO=0x0, fSource="", fTarget="", flags=0x0, ghwnd=0x0 )     
{
    
    If ( SubStr(fSource,0) != "|" )
        fSource := fSource . "|"

    If ( SubStr(fTarget,0) != "|" )
        fTarget := fTarget . "|"
    
    char_size := A_IsUnicode ? 2 : 1
    char_type := A_IsUnicode ? "UShort" : "Char"
    
    fsPtr := &fSource
    Loop % StrLen(fSource)
        if NumGet(fSource, (A_Index-1)*char_size, char_type) = 124
            NumPut(0, fSource, (A_Index-1)*char_size, char_type)

    ftPtr := &fTarget
    Loop % StrLen(fTarget)
        if NumGet(fTarget, (A_Index-1)*char_size, char_type) = 124
            NumPut(0, fTarget, (A_Index-1)*char_size, char_type)
    
    VarSetCapacity( SHFILEOPSTRUCT, 60, 0 )                 ; Encoding SHFILEOPSTRUCT
    NextOffset := NumPut( ghwnd, &SHFILEOPSTRUCT )          ; hWnd of calling GUI
    NextOffset := NumPut( fileO, NextOffset+0    )          ; File operation
    NextOffset := NumPut( fsPtr, NextOffset+0    )          ; Source file / pattern
    NextOffset := NumPut( ftPtr, NextOffset+0    )          ; Target file / folder
    NextOffset := NumPut( flags, NextOffset+0, 0, "Short" ) ; options

    DllCall( "Shell32\SHFileOperation" . (A_IsUnicode ? "W" : "A"), UInt,&SHFILEOPSTRUCT )
    
    Return NumGet( NextOffset+0 )
}