Что нового

Как сохранить содержимое буфера обмена в файл

Сообщения
80
Репутация
-1
Доброго дня.
Как при помощи au3 - сохранить содержимое буфера обмена в файл ?
В буфере обмена может быть что угодно - фото, видео, форматированный текст и т.д. То есть все что можно положить в буфер обмена.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
Код:
#include <Clipboard.au3>

Global $sCB_File = @ScriptDir & '\ClipBoard.ini'
Global $hGUI = GUICreate('')

Global $iFormat = 0
Global $aSects = IniReadSectionNames($sCB_File)
Global $iSect = (IsArray($aSects) ? $aSects[0] : 0)

Do
    _ClipBoard_Open($hGUI)
    $iFormat = _ClipBoard_EnumFormats($iFormat)
    _ClipBoard_Close()
   
    If $iFormat <> 0 Then
        $vData = _ClipBoard_GetData($iFormat)
       
        If Not IsBinary($vData) Then
            $vData = StringToBinary($vData)
        EndIf
       
        IniWrite($sCB_File, 'CB' & ($iSect + 1), $iFormat, $vData)
    EndIf
Until $iFormat = 0
 
Автор
D
Сообщения
80
Репутация
-1
CreatoR
Ясно, спасибо.
А как вставить в буфер - то что записано в этом ini ?

А то - не получается проверить что именно туда записалось.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
как вставить в буфер - то что записано в этом ini ?
Код:
#include <Clipboard.au3>

Global $sCB_File = @ScriptDir & '\ClipBoard.ini'
Global $aSect = IniReadSection($sCB_File, 'CB1')

For $i = 1 To UBound($aSect) - 1
    If $aSect[$i][0] = $CF_TEXT Or $aSect[$i][0] = $CF_OEMTEXT Or $aSect[$i][0] = $CF_UNICODETEXT Or $aSect[$i][0] = $CF_DSPTEXT Then
        $aSect[$i][1] = BinaryToString($aSect[$i][1])
    EndIf
   
    _ClipBoard_SetData($aSect[$i][1], $aSect[$i][0])
Next
 
Последнее редактирование:

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
Вот сделал в виде функции:

Код:
#include <Clipboard.au3>
#include <WinAPIFiles.au3>

Global $sCB_File = @ScriptDir & '\ClipBoard.ini'
Global $aSects = IniReadSectionNames($sCB_File)
Global $iSect = (IsArray($aSects) ? $aSects[0] : 0)

;Capture image
Send('{PRINTSCREEN}')
Sleep(200)

_ClipBoard_SaveToFile($sCB_File, 'CB' & $iSect + 1)

;Put some text to clipboard
ClipPut('')
ClipPut('Some text')
Sleep(200)

_ClipBoard_SaveToFile($sCB_File, 'CB' & $iSect + 2)

;Restore captured screenshot
_ClipBoard_LoadFromFile($sCB_File, 'CB' & $iSect + 1)

Func _ClipBoard_LoadFromFile($sFile, $sSect)
    Local $aSect = IniReadSection($sFile, $sSect)
   
    For $i = 1 To UBound($aSect) - 1
        Switch $aSect[$i][0]
            Case $CF_TEXT, $CF_OEMTEXT, $CF_UNICODETEXT, $CF_DSPTEXT
                $aSect[$i][1] = BinaryToString($aSect[$i][1])
        EndSwitch
       
        If IsString($aSect[$i][1]) And FileExists($aSect[$i][1]) Then
            $aSect[$i][1] = Binary(FileRead($aSect[$i][1]))
        EndIf
       
        _ClipBoard_SetData($aSect[$i][1], $aSect[$i][0])
    Next
EndFunc

Func _ClipBoard_SaveToFile($sFile, $sSect)
    Local $hGUI = GUICreate('')
    Local $iFormat = 0, $vData
   
    Do
        _ClipBoard_Open($hGUI)
        $iFormat = _ClipBoard_EnumFormats($iFormat)
        _ClipBoard_Close()
       
        If $iFormat <> 0 Then
            $vData = _ClipBoard_GetData($iFormat)
           
            Switch $iFormat
                Case $CF_TEXT, $CF_OEMTEXT, $CF_UNICODETEXT, $CF_DSPTEXT
                    $vData = StringToBinary($vData)
                Case Else
                    If BinaryLen($vData) > (30 * 1024) Then
                        $sTmp = _WinAPI_GetTempFileName(StringRegExpReplace($sFile, '\\[^\\]+$', ''), 'CBFile_')
                       
                        $hFile = FileOpen($sTmp, 18)
                        FileWrite($hFile, $vData)
                        FileClose($hFile)
                       
                        $vData = $sTmp
                    EndIf
            EndSwitch
           
            IniWrite($sFile, $sSect, $iFormat, $vData)
        EndIf
    Until $iFormat = 0
   
    GUIDelete($hGUI)
EndFunc


Для больших данных (изображения) сохраняет в отдельный файл.
 
Автор
D
Сообщения
80
Репутация
-1
CreatoR
Так как же вставить в буфер обмена - информацию из файла ini ?
Я же не могу проверить работу скрипта - если этого нет.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
не могу проверить работу скрипта - если этого нет.
Кого нет?
В последнем примере показано как записываются данные в файл, и как они восстанавливаются в буфер обмена.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
Вот немного переделал, избавился от ini (для каждого сохранения отдельный файл):

Код:
#include <Clipboard.au3>

Global $sCB_Img_File = @ScriptDir & '\ClipBoard_Img.ini'
Global $sCB_Txt_File = @ScriptDir & '\ClipBoard_Txt.ini'

;Capture image
Send('!{PRINTSCREEN}')
Sleep(200)

_ClipBoard_SaveToFile($sCB_Img_File)

;Put some text to clipboard
ClipPut('')
ClipPut('Some text')
Sleep(200)

_ClipBoard_SaveToFile($sCB_Txt_File)

;Restore captured screenshot
_ClipBoard_LoadFromFile($sCB_Img_File)

Func _ClipBoard_LoadFromFile($sFile)
    Local $aSect = StringRegExp(FileRead($sFile), '(?ms)^([^=]+)=([^\r\n]+)$', 3)
    
    If Not IsArray($aSect) Or Mod(UBound($aSect), 2) <> 0 Then
        Return SetError(1, 0, 0)
    EndIf
    
    For $i = 0 To UBound($aSect) - 1 Step 2
        Switch $aSect[$i]
            Case $CF_TEXT, $CF_OEMTEXT, $CF_UNICODETEXT, $CF_DSPTEXT
                $aSect[$i + 1] = BinaryToString($aSect[$i + 1])
        EndSwitch
        
        _ClipBoard_SetData($aSect[$i + 1], $aSect[$i])
    Next
EndFunc

Func _ClipBoard_SaveToFile($sFile)
    Local $hGUI = GUICreate('')
    Local $iFormat = 0, $vData
    Local $sData = '', $hFile
    
    Do
        _ClipBoard_Open($hGUI)
        $iFormat = _ClipBoard_EnumFormats($iFormat)
        _ClipBoard_Close()
        
        If $iFormat <> 0 Then
            $vData = _ClipBoard_GetData($iFormat)
            
            Switch $iFormat
                Case $CF_TEXT, $CF_OEMTEXT, $CF_UNICODETEXT, $CF_DSPTEXT
                    $vData = StringToBinary($vData)
            EndSwitch
            
            $sData &= ($sData ? @CRLF : '') & $iFormat & '=' & $vData
        EndIf
    Until $iFormat = 0
    
    $hFile = FileOpen($sFile, 2)
    FileWrite($hFile, $sData)
    FileClose($hFile)
    
    GUIDelete($hGUI)
EndFunc
 
Автор
D
Сообщения
80
Репутация
-1
CreatoR
Большое спасибо, но я по-прежнему не могу запустить этот скрипт.

Вот я сейчас скопировал папку с файлами на 15мб, запускаю макрос - он создает два файла - один на 86 байт и другой на 5 килобайт.
Там записалось явно - не содержимое буфера обмена.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
скопировал папку с файлами на 15мб, запускаю макрос - он создает два файла - один на 86 байт и другой на 5 килобайт
Всё верно, при копировании файлов в буфер обмена попадают пути к файлам, а не содержимое файлов.
В доказательство этому, скопируй файлы и запусти этот скрипт:
Код:
MsgBox(64, @ScriptName, ClipGet())


Там записалось явно - не содержимое буфера обмена
Содержимое в бинарном виде.
 
Автор
D
Сообщения
80
Репутация
-1
Содержимое в бинарном виде.
Я все понимаю, но как мне поместить в буфер обмена - содержимое этого файла ini (которое находится в бинарном виде) ?
Как скриптом автоит - скопировать содержимое - созданного файла ini в буфер обмена ?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
Как скриптом автоит - скопировать содержимое - созданного файла ini в буфер обмена ?
Я это показал в примерах выше.
Либо я не понимаю что ты пытаешься сделать. Опиши действие, ожидание, и результат.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
Поправил ещё немного функции, чтобы сохранялись и восстанавливались пути к файлам ($CF_HDROP).

Код:
#include <Clipboard.au3>
#include <Misc.au3>

Func _ClipBoard_LoadFromFile($sFile)
    Local $aSect = StringRegExp(FileRead($sFile), '(?ms)^([^=]+)=([^\r\n]+)$', 3)
   
    If Not IsArray($aSect) Or Mod(UBound($aSect), 2) <> 0 Then
        Return SetError(1, 0, 0)
    EndIf
   
    For $i = 0 To UBound($aSect) - 1 Step 2
        $aSect[$i] = Int($aSect[$i])
       
        Switch $aSect[$i]
            Case $CF_TEXT, $CF_OEMTEXT, $CF_UNICODETEXT, $CF_DSPTEXT
                $aSect[$i + 1] = BinaryToString($aSect[$i + 1])
            Case $CF_HDROP
                _ClipPutFile(BinaryToString($aSect[$i + 1]), @LF)
                Sleep(100)
        EndSwitch
       
        _ClipBoard_SetData($aSect[$i + 1], $aSect[$i])
    Next
EndFunc

Func _ClipBoard_SaveToFile($sFile)
    Local $hGUI = GUICreate('')
    Local $iFormat = 0, $vData
    Local $sData = '', $hFile
   
    Do
        _ClipBoard_Open($hGUI)
        $iFormat = _ClipBoard_EnumFormats($iFormat)
        _ClipBoard_Close()
       
        If $iFormat <> 0 Then
            $vData = _ClipBoard_GetData($iFormat)
           
            Switch $iFormat
                Case $CF_TEXT, $CF_OEMTEXT, $CF_UNICODETEXT, $CF_DSPTEXT
                    $vData = StringToBinary($vData)
                Case $CF_HDROP
                    $vData = StringToBinary(ClipGet())
            EndSwitch
           
            $sData &= ($sData ? @CRLF : '') & $iFormat & '=' & $vData
        EndIf
    Until $iFormat = 0
   
    $hFile = FileOpen($sFile, 2)
    FileWrite($hFile, $sData)
    FileClose($hFile)
   
    GUIDelete($hGUI)
EndFunc
 
Автор
D
Сообщения
80
Репутация
-1
не работает.
Скопировал в буфер обмена, запустил скрипт - никаких ini файлов рядом - не появилось.

Либо я не понимаю что ты пытаешься сделать.
Я пытаюсь протестировать ваш скрипт.
Он что-то записал в ini-файл.
Но что именно там находится - я пока не знаю (возможно скрипт записал в ini то что находится в буфере обмена, а возможно он записал это частично, неполностью, записав например один текст, но с утратой форматирования и т.д.).

И вот чтобы проверить это (что именно находится в буфере обмена, правильно ли оно туда скопировалось, не потерялось ли чего) - я хочу поместить содержимое файла ini - обратно в буфер обмена.
Чтобы нажав на клавиатуре сочетание клавиш Ctrl+V у меня бы вставилось это содержимое из буфера обмена. И мне стало бы ясно - что скрипт работает, что в ini файл - копирование из буфера совершается хорошо.
 
Автор
D
Сообщения
80
Репутация
-1
Что скопировал?

Файл скопировал в буфер, запустил скрипт - не создается ini
Папку скопировал, запустил скрипт - не создается ini
Картинку скопировал - тоже ничего не создается.
Текст скопировал в буфер - тоже никакого эффекта.
Таблицу в экселе скопировал - не создается ini.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
С форматами я немного погорячился, там не всё так просто.
Можно сохранить (и восстановить) обычный текст, картинку, список файлов, но вот разные форматирования типа RichText будет сложнее...
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,485
А можно вопрос, зачем это нужно?
Если нет планов создать аналог типа ClipDiary, то не вижу в этом особого смысла.
 

lemonia

Новичок
Сообщения
126
Репутация
0
А как выглядит полный код скрипта для Windows 10, чтобы скопированные в буфер обмена фрагменты текста, при каждом новом копировании попадали в один и тот же текстовой файл и между фрагментами вставлялась пустая строка? Такую программу не нашел. Знаю одну, только она хорошо работает в Windows Xp, а не в десятке.
 
Верх