1

Тема: AHK: Добавить папку в буфер обмена.

Хочу в своем скрипте, копировать папку, но я так понял простым:

Clipboard

тут не обойтись.
Искал в интернете, может кто то делал уже, нашел 2 скрипта, но они для копирования файлов, но они как то не копируют:
вот 1ый

FileToClipboard("test.mkv")

FileToClipboard(PathToCopy)
{
    ; Expand to full paths:
    Loop, Parse, PathToCopy, `n, `r
        Loop, %A_LoopField%, 1
            temp_list .= A_LoopFileLongPath "`n"
    PathToCopy := SubStr(temp_list, 1, -1)
    
    ; Allocate some movable memory to put on the clipboard.
    ; This will hold a DROPFILES struct and a null-terminated list of
    ; null-terminated strings.
    ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
    hPath := DllCall("GlobalAlloc","uint",0x42,"uint",StrLen(PathToCopy)+22)
    
    ; Lock the moveable memory, retrieving a pointer to it.
    pPath := DllCall("GlobalLock","uint",hPath)
    
    NumPut(20, pPath+0) ; DROPFILES.pFiles = offset of file list
    
    pPath += 20
    ; Copy the list of files into moveable memory.
    Loop, Parse, PathToCopy, `n, `r
    {
        DllCall("lstrcpy","uint",pPath+0,"str",A_LoopField)
        pPath += StrLen(A_LoopField)+1
    }
    
    ; Unlock the moveable memory.
    DllCall("GlobalUnlock","uint",hPath)
    
    DllCall("OpenClipboard","uint",0)
    ; Empty the clipboard, otherwise SetClipboardData may fail.
    DllCall("EmptyClipboard")
    ; Place the data on the clipboard. CF_HDROP=0xF
    DllCall("SetClipboardData","uint",0xF,"uint",hPath)
    DllCall("CloseClipboard")
}

Второй:

F12::
list := ""
path := Explorer_GetPath() 
Loop, Files, %path%\*.*
   {
   SplitPath, A_LoopFileName ,  ,  ,  , OutNameNoExt
   list .= OutNameNoExt "`n"
   }
Clipboard := list
return

Explorer_GetPath() {
   WinGetClass, winClass, % "ahk_id" . hWnd := WinExist("A")
   if !(winClass ~= "(Cabinet|Explore)WClass")
      Return
   for window in ComObjCreate("Shell.Application").Windows
      if (hWnd = window.hWnd)
         return window.Document.Folder.Self.Path
}

Возможно ли в AHK копировать папку в буфер обмена?

2

Re: AHK: Добавить папку в буфер обмена.

Что именно под 'копировать папку' вы имеете в виду? Название, путь, список всех файлов?

Win10x64, AHK v1.1.37.01 (Unicode 64-bit), AHK v2.0.17| AHK-Wiki | Переменные и выражения | RegEx101

3 (изменено: YMP, 2023-08-18 20:19:44)

Re: AHK: Добавить папку в буфер обмена.

D@rkSIDeR008 пишет:

нашел 2 скрипта, но они для копирования файлов, но они как то не копируют:

Второй же просто Clipboard использует. А первый был написан для ANSI. Для Юникодного АНК должно так работать. Если несколько путей, то каждый должен быть на новой строке.


FileToClipboard(PathToCopy)

FileToClipboard(PathToCopy)
{
    ; Expand to full paths:
    Loop, Parse, PathToCopy, `n, `r
        Loop, %A_LoopField%, 1
            temp_list .= A_LoopFileLongPath "`n"
    PathToCopy := SubStr(temp_list, 1, -1)
    
    ; Allocate some movable memory to put on the clipboard.
    ; This will hold a DROPFILES struct and a null-terminated list of
    ; null-terminated strings.
    ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
    hPath := DllCall("GlobalAlloc","uint",0x42,"ptr",StrLen(PathToCopy)*2+24)
    
    ; Lock the moveable memory, retrieving a pointer to it.
    pPath := DllCall("GlobalLock","ptr",hPath)
    
    NumPut(20, pPath+0, 0, "uint")  ; DROPFILES.pFiles = offset of file list
    NumPut(1, pPath+0, 16, "uint")  ; File names are in Unicode.
    
    pPath += 20
    ; Copy the list of files into moveable memory.
    Loop, Parse, PathToCopy, `n, `r
    {
        DllCall("lstrcpyW","ptr",pPath+0,"str",A_LoopField)
        pPath += (StrLen(A_LoopField)+1) * 2
    }
    
    ; Unlock the moveable memory.
    DllCall("GlobalUnlock","ptr",hPath)
    
    DllCall("OpenClipboard","ptr",0)
    ; Empty the clipboard, otherwise SetClipboardData may fail.
    DllCall("EmptyClipboard")
    ; Place the data on the clipboard. CF_HDROP=0xF
    DllCall("SetClipboardData","uint",0xF,"ptr",hPath)
    DllCall("CloseClipboard")
}

4

Re: AHK: Добавить папку в буфер обмена.

__Михаил__ пишет:

Что именно под 'копировать папку' вы имеете в виду? Название, путь, список всех файлов?

Я имею ввиду скопировать в буфер обмена саму папку, путь я уже скопировал:

ControlSend,, {CTRLDOWN}c{CTRLUP}, ahk_class #32770
Sleep, 200
Q2 := ClipboardAll

Теперь мне нужно скопировать саму папку из этого пути.

5

Re: AHK: Добавить папку в буфер обмена.

YMP пишет:
D@rkSIDeR008 пишет:

нашел 2 скрипта, но они для копирования файлов, но они как то не копируют:

Второй же просто Clipboard использует. А первый был написан для ANSI. Для Юникодного АНК должно так работать. Если несколько путей, то каждый должен быть на новой строке.


FileToClipboard(PathToCopy)

FileToClipboard(PathToCopy)
{
    ; Expand to full paths:
    Loop, Parse, PathToCopy, `n, `r
        Loop, %A_LoopField%, 1
            temp_list .= A_LoopFileLongPath "`n"
    PathToCopy := SubStr(temp_list, 1, -1)
    
    ; Allocate some movable memory to put on the clipboard.
    ; This will hold a DROPFILES struct and a null-terminated list of
    ; null-terminated strings.
    ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
    hPath := DllCall("GlobalAlloc","uint",0x42,"ptr",StrLen(PathToCopy)*2+24)
    
    ; Lock the moveable memory, retrieving a pointer to it.
    pPath := DllCall("GlobalLock","ptr",hPath)
    
    NumPut(20, pPath+0, 0, "uint")  ; DROPFILES.pFiles = offset of file list
    NumPut(1, pPath+0, 16, "uint")  ; File names are in Unicode.
    
    pPath += 20
    ; Copy the list of files into moveable memory.
    Loop, Parse, PathToCopy, `n, `r
    {
        DllCall("lstrcpyW","ptr",pPath+0,"str",A_LoopField)
        pPath += (StrLen(A_LoopField)+1) * 2
    }
    
    ; Unlock the moveable memory.
    DllCall("GlobalUnlock","ptr",hPath)
    
    DllCall("OpenClipboard","ptr",0)
    ; Empty the clipboard, otherwise SetClipboardData may fail.
    DllCall("EmptyClipboard")
    ; Place the data on the clipboard. CF_HDROP=0xF
    DllCall("SetClipboardData","uint",0xF,"ptr",hPath)
    DllCall("CloseClipboard")
}

Ну я пробовал прописывать путь к папке или файлу, скрипт что то явно добавляет в буфер обмена, но не файл, который я вписал.

6

Re: AHK: Добавить папку в буфер обмена.

Либо я что то не так вписываю.

7

Re: AHK: Добавить папку в буфер обмена.

D@rkSIDeR008
Ну так попробуйте потом вставить где-нибудь и увидите, что было в буфере. Или какая ошибка вылезет.

А путь должен быть либо полный, либо относительно рабочего каталога скрипта.

8

Re: AHK: Добавить папку в буфер обмена.

YMP
А я выше описывал, но наверно не понятно написал. После использования скрипта, я вставляю в папку, но ничего не вставляется, происходит какая то прогрузка как будто что то вставилось и курсор не надолго меняется на прогрузочный типа с песочными часами. Так же я порбовал вставить в текстовое поле на всякий случай но и там пустота. А пусть я указываю полный, еще пробовал просто имя файла писать и файл ложил рядом со скриптом, еще пробовал прописывать:

%A_ScriptDir%

Но ничего не помогло.

9

Re: AHK: Добавить папку в буфер обмена.

Ну и еще все скрипты которые я находил, они для копирования файлов но не для копирования папки, которое мне так нужно.

10

Re: AHK: Добавить папку в буфер обмена.

D@rkSIDeR008
Проверил ещё раз, скопировав код из моего поста выше, у меня работает и для файлов, и для папок. На Windows 10.

У вас АНК какой?

11

Re: AHK: Добавить папку в буфер обмена.

YMP пишет:

D@rkSIDeR008
Проверил ещё раз, скопировав код из моего поста выше, у меня работает и для файлов, и для папок. На Windows 10.

У вас АНК какой?

У меня WIN8.1, а AHK  я обе версии поставил, но что бы работала 2ая вроде нужно в начале скрипта указывать, значит работает первая версия, но она у меня последняя, я с сайта недавно качал.

12

Re: AHK: Добавить папку в буфер обмена.

Не могли бы вы скинуть код, где вы вставили в скрипт путь к папке.

13

Re: AHK: Добавить папку в буфер обмена.

Так что там скидывать? Код тот же, что выше в моём посте, я оттуда скопировал. В первой строчке, где вызов функции, вставил вместо PathToCopy путь к папке.

Что у вас вот этот код показывает про ваш АНК?


MsgBox, % (A_IsUnicode ? "U":"A") . (A_PtrSize == 8 ? 64:32) . " " . A_AhkVersion

14

Re: AHK: Добавить папку в буфер обмена.

YMP
U64 1.1.36.02

15

Re: AHK: Добавить папку в буфер обмена.

У меня старее была, а последняя уже  1.1.37.01. Обновил до неё, всё равно всё работает. Проверил ещё на Windows XP SP3, тоже работает. Не знаю, что у вас может быть.

16

Re: AHK: Добавить папку в буфер обмена.

И на Windows 7 SP1 работает.

17

Re: AHK: Добавить папку в буфер обмена.

Спасибо, я обновил AHK заработало.
Но у меня путь к папке в буфере обмена.

FolderPath := Trim(Clipboard)
Sleep, 500

ControlClick, Со&хранить, ahk_class #32770
Send, {Space}
Sleep, 500

FileToClipboard("%FolderPath%")

FileToClipboard(PathToCopy)
{
    ; Expand to full paths:
    Loop, Parse, PathToCopy, `n, `r
        Loop, %A_LoopField%, 1
            temp_list .= A_LoopFileLongPath "`n"
    PathToCopy := SubStr(temp_list, 1, -1)

    ; Allocate some movable memory to put on the clipboard.
    ; This will hold a DROPFILES struct and a null-terminated list of
    ; null-terminated strings.
    ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
    hPath := DllCall("GlobalAlloc","uint",0x42,"ptr",StrLen(PathToCopy)*2+24)

    ; Lock the moveable memory, retrieving a pointer to it.
    pPath := DllCall("GlobalLock","ptr",hPath)

    NumPut(20, pPath+0, 0, "uint")  ; DROPFILES.pFiles = offset of file list
    NumPut(1, pPath+0, 16, "uint")  ; File names are in Unicode.

    pPath += 20
    ; Copy the list of files into moveable memory.
    Loop, Parse, PathToCopy, `n, `r
    {
        DllCall("lstrcpyW","ptr",pPath+0,"str",A_LoopField)
        pPath += (StrLen(A_LoopField)+1) * 2
    }

    ; Unlock the moveable memory.
    DllCall("GlobalUnlock","ptr",hPath)

    DllCall("OpenClipboard","ptr",0)
    ; Empty the clipboard, otherwise SetClipboardData may fail.
    DllCall("EmptyClipboard")
    ; Place the data on the clipboard. CF_HDROP=0xF
    DllCall("SetClipboardData","uint",0xF,"ptr",hPath)
    DllCall("CloseClipboard")
}

То есть я копирую путь к папке и открываю скрипт, но видимо что то не так вставляется.

18 (изменено: D@rkSIDeR008, 2023-08-19 13:25:42)

Re: AHK: Добавить папку в буфер обмена.

Либо так нельзя делать, я проверил написал до кода копирования MsBox и в нем выдает правильный путь, но он не вставляется дальше, потому что я проверил буфер обмена другим скриптом:

FileAppend, %ClipboardAll%, 1.txt ;

и там почти пустой файл выходит, без путей. Обычно когда копируешь папку, она в текстовом документе записывает кучу символов и 3 раза путь к папке, 2 раза с пробелами между каждым символом и 1 раз обычно, ну это как я понял по крайней мере.

19

Re: AHK: Добавить папку в буфер обмена.

Да, действительно через переменную, не вставляется путь в FileToClipboard(PathToCopy).
Я переделал немного код для проверки:

FolderPath := "C:\Users\User\Downloads\Диван Лайм 2-х местный мод 337968 Era cotton орех лак (РФ)"
Sleep, 500

MsgBox, %FolderPath%


FileToClipboard("%FolderPath%")

FileToClipboard(PathToCopy)
{
    ; Expand to full paths:
    Loop, Parse, PathToCopy, `n, `r
        Loop, %A_LoopField%, 1
            temp_list .= A_LoopFileLongPath "`n"
    PathToCopy := SubStr(temp_list, 1, -1)

    ; Allocate some movable memory to put on the clipboard.
    ; This will hold a DROPFILES struct and a null-terminated list of
    ; null-terminated strings.
    ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
    hPath := DllCall("GlobalAlloc","uint",0x42,"ptr",StrLen(PathToCopy)*2+24)

    ; Lock the moveable memory, retrieving a pointer to it.
    pPath := DllCall("GlobalLock","ptr",hPath)

    NumPut(20, pPath+0, 0, "uint")  ; DROPFILES.pFiles = offset of file list
    NumPut(1, pPath+0, 16, "uint")  ; File names are in Unicode.

    pPath += 20
    ; Copy the list of files into moveable memory.
    Loop, Parse, PathToCopy, `n, `r
    {
        DllCall("lstrcpyW","ptr",pPath+0,"str",A_LoopField)
        pPath += (StrLen(A_LoopField)+1) * 2
    }

    ; Unlock the moveable memory.
    DllCall("GlobalUnlock","ptr",hPath)

    DllCall("OpenClipboard","ptr",0)
    ; Empty the clipboard, otherwise SetClipboardData may fail.
    DllCall("EmptyClipboard")
    ; Place the data on the clipboard. CF_HDROP=0xF
    DllCall("SetClipboardData","uint",0xF,"ptr",hPath)
    DllCall("CloseClipboard")
}

вот так не работает.
Ну по крайней мере у меня.

20

Re: AHK: Добавить папку в буфер обмена.

D@rkSIDeR008 пишет:
FileToClipboard("%FolderPath%")

Не, надо так:


FileToClipboard(FolderPath)

Функциям нужно просто имя переменной, без процентов и кавычек.

21

Re: AHK: Добавить папку в буфер обмена.

Интересно, в отдельном скрипте это все работает и копирует, но как только я его добавляю в общий скрипт, большой, то он перестает копировать.

22

Re: AHK: Добавить папку в буфер обмена.





PID:=DllCall("GetCurrentProcessId")
query:="SELECT Handle FROM Win32_Process WHERE Caption='AutoHotkey.exe'"

If (oWMI:=ComObjGet("winmgmts:").ExecQuery(query)).Count>1
   For colItem In oWMI
      If colItem.Handle!=PID
         colItem.Terminate()



FileToClipboard(PathToCopy)
{
    ; Expand to full paths:
    temp_list := A_LoopFileLongPath "`n"

    Loop, Parse, PathToCopy, `n, `r
        Loop, %A_LoopField%, 1
            temp_list .= A_LoopFileLongPath "`n"
    PathToCopy := SubStr(temp_list, 1, -1)

    ; Allocate some movable memory to put on the clipboard.
    ; This will hold a DROPFILES struct and a null-terminated list of
    ; null-terminated strings.
    ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
    hPath := DllCall("GlobalAlloc","uint",0x42,"ptr",StrLen(PathToCopy)*2+24)

    ; Lock the moveable memory, retrieving a pointer to it.
    pPath := DllCall("GlobalLock","ptr",hPath)

    NumPut(20, pPath+0, 0, "uint")  ; DROPFILES.pFiles = offset of file list
    NumPut(1, pPath+0, 16, "uint")  ; File names are in Unicode.

    pPath += 20
    ; Copy the list of files into moveable memory.
    Loop, Parse, PathToCopy, `n, `r
    {
        DllCall("lstrcpyW","ptr",pPath+0,"str",A_LoopField)
        pPath += (StrLen(A_LoopField)+1) * 2
    }

    ; Unlock the moveable memory.
    DllCall("GlobalUnlock","ptr",hPath)

    DllCall("OpenClipboard","ptr",0)
    ; Empty the clipboard, otherwise SetClipboardData may fail.
    DllCall("EmptyClipboard")
    ; Place the data on the clipboard. CF_HDROP=0xF
    DllCall("SetClipboardData","uint",0xF,"ptr",hPath)
    DllCall("CloseClipboard")
}



Sleep, 200

CapsLock::

Q1 :=ClipboardAll
Sleep, 200

WinActivate, ahk_class Chrome_WidgetWin_1
Sleep, 350
  SendMessage, 0x50,, 0x4090409,, A ; английский
Sleep, 200
Click right
Sleep, 100
SetCapsLockState, off
Sleep, 550

ImageSearch, FoundX, FoundY, 1, 1, 1373, 732, %A_ScriptDir%\img\Save_ImageAs.png
sleep, 200
if ErrorLevel = 2
   {
    MsgBox Произвести поиск невозможно.
    Reload
   }
else if ErrorLevel = 1
   {
   MsgBox Изображение не найдено на экране.
    Reload
   }
else
   {
    Click %FoundX%, %FoundY%
   }

Sleep, 200
ControlSend,, {Right}{Down}, ahk_class Chrome_WidgetWin_1
Sleep, 350
ControlSend,, {Enter}, ahk_class Chrome_WidgetWin_1
Sleep, 200
WinWait, ahk_class #32770,
IfWinNotActive, ahk_class #32770, , WinActivate, ahk_class #32770,
WinWaitActive, ahk_class #32770,
Sleep, 200
  SendMessage, 0x50,, 0x4090409,, A ; английский
Sleep, 300
ControlSend,, {CTRLDOWN}c{CTRLUP}, ahk_class #32770
Sleep, 200
Q2 := ClipboardAll
Sleep, 200
DOWNLOAD:= "C:\Users\User\Downloads\"
Sleep, 200
ControlSend,, %DOWNLOAD%, ahk_class #32770
Sleep, 500
Send, {Enter}
Sleep, 200
ControlClick, x206 y82, ahk_class #32770
Sleep, 100
Send, {Space}
Sleep, 200
Clipboard:= Q1
Sleep, 350
Send, {CTRLDOWN}v{CTRLUP}
Sleep, 500
Send, {Enter}
Sleep, 200

IfWinActive, переименование
{
   Sleep, 300
   ControlSend,, {Enter}, переименование
   Sleep, 650
}

IfWinActive, Подтверждение замены папки
{
   Sleep, 300
   Send, {Enter}
   Sleep, 650
}

Send, {Enter}
Sleep, 200
ControlClick, x261 y373, Сохранение


Sleep, 350
Clipboard:= Q2
Sleep, 500
Send, {CTRLDOWN}v{CTRLUP}
Sleep, 500

WinActivate, ahk_class #32770
Sleep, 200
MouseClick, right,  378,  47
Sleep, 200
Send, {Down}{Down}{Enter}
Sleep, 200
Send, {Tab}
Sleep, 100
Send, {Tab}
Sleep, 500
FolderPath := Trim(Clipboard)
Sleep, 500

ControlClick, Со&хранить, ahk_class #32770
Send, {Space}
Sleep, 500

Clipboard:= ""
Sleep, 200

FileToClipboard(FolderPath)

Sleep, 500
MsgBox, %FolderPath%

23

Re: AHK: Добавить папку в буфер обмена.

Вроде, все что мог лишнее убрал, думал мешает буфер обмена, добавил перед кодом:

Clipboard:= ""

что бы почистить буфер обмена.
Но тоже не помогло.

24

Re: AHK: Добавить папку в буфер обмена.

Хм, а сейчас вообще странно, переписал то же самое заново в новом документе, и все заработало.

25

Re: AHK: Добавить папку в буфер обмена.

YMP
Большое Вам спасибо.