python-剪貼板的操作-文件相關(復制文件到剪貼板,剪切文件到剪貼板)


  1. 讀取有沒有文件被復制或剪切
import win32clipboard

a = ""
clip = win32clipboard.RegisterClipboardFormat("Preferred DropEffect")
#返回的clip 就是我們將要代入GetClipboardData函數的該數據結構的代碼
if win32clipboard.OpenClipboard() == None:
    try:
        #嘗試以文件的格式讀取剪貼板內容
        clip_ = win32clipboard.GetClipboardData(win32clipboard.CF_HDROP)
        if clip_ != None:
            #獲取標志位
            a = win32clipboard.GetClipboardData(clip)
    finally:
        win32clipboard.CloseClipboard()
if a[0] == 2:
    print("剪切")
elif a[0] == 5:
    print("復制")
else:
    print(a[0])    

關於“clip = win32clipboard.RegisterClipboardFormat("Preferred DropEffect")”,其中Preferred DropEffect是系統定義的一個關於如何處理文件(復制,移動等)的剪貼板格式字符串,我們在這里同樣注冊這個,不會與系統發生沖突,重復注冊也只是會返回第一次注冊的句柄值;收到這篇博客的啟發:傳送門:如何與資源管理器互動剪切/拷貝/粘貼文件_xuyongbeijing2008的專欄-CSDN博客

我做了更詳細的測試:

#這些函數相關的作用,請參考:http://timgolden.me.uk/pywin32-docs/win32clipboard.html
import
win32clipboard
win32clipboard.OpenClipboard()
format = 0
str_list = []
try:
    while True:
        ret = win32clipboard.EnumClipboardFormats(format)  #獲取當前剪貼板上的數據格式
        if ret == 0:
            print("ret={}".format(ret))
            break
        ret_str = win32clipboard.GetClipboardFormatName(ret)  #以字符串形式返回格式名稱
        print("format={}\tstring={}".format(format,ret_str))
        
        conten_str = win32clipboard.GetClipboardData(ret)  #獲取數據
        print("\t{}".format(conten_str))
        str_list.append(conten_str)
        format = ret
except Exception as e:
    ctypes.GetLastError()
finally:
    win32clipboard.CloseClipboard()

這是在文件資源管理器上做了剪切文件的操作在運行代碼的輸出:

format=0 string=DataObject
format=49161 string=Shell IDList Array
b"\x01\x00\x00\x00\x0c\x00\x00\x00\x15\x01\x00\x00\x14\x00\x1fP\xe0O\xd0 \xea:i\x10\xa2\xd8\x08\x00+00\x9d\x19\x00/D:\\\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x001\x00\x00\x00\x00\x009T\xaa<\x10\x00python\x00\x00>\x00\t\x00\x04\x00\xef\xbe9T\xa1<9T\xaa<.\x00\x00\x00\xca\x01\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xef\x0f\x00p\x00y\x00t\x00h\x00o\x000\x00\xac)\x9c\x00p\x00y\x00t\x00h\x00o\x00n\x00_\x00c\x00l\x00a\x00s\x00s\x00_\x00e\x00v\x00e\x00r\x00y\x00t\x00h\x00i\x00n\x00g\x00\x00\x00&\x00\x00\x00\x84\x002\x00%\x04\x00\x00OT\xf7L \x00python_everything.spec\x00\x00^\x00\t\x00\x04\x00\xef\xbeJT\xc1AOT\xf7L.\x00\x00\x00:\n\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xd9j\x00p\x00y\x00t\x00h\x00o\x00n\x00_\x00e\x00v\x00e\x00r\x00y\x00t\x00h\x00i\x00n\x00g\x00.\x00s\x00p\x00e\x00c\x00\x00\x00&\x00\x00\x00"
format=49390 string=DataObjectAttributes
format=50001 string=DataObjectAttributesRequiringElevation
b'0\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
format=50000 string=Shell Object Offsets
b'I\x04\x00\x00\x17\x03\x00\x00'
format=49391 string=Preferred DropEffect
b'\x02\x00\x00\x00'
format=49399 string=AsyncFlag
b'\x01\x00\x00\x00'

 

  1. 實現復制文件操作,復制操作可以不用設置標志位
#參考:https://chowdera.com/2021/10/20211031055535475l.html
#這其實是一個結構體,用以記錄文件的各種信息。
class DROPFILES(ctypes.Structure):
    _fields_ = [
        ("pFiles", ctypes.c_uint),
        ("x", ctypes.c_long),
        ("y", ctypes.c_long),
        ("fNC", ctypes.c_int),
        ("fWide", ctypes.c_bool),
    ]

pDropFiles = DROPFILES()
pDropFiles.pFiles = ctypes.sizeof(DROPFILES)
pDropFiles.fWide = True
a = bytes(pDropFiles)

#獲取文件絕對路徑
filepaths_list = [文件路徑1,文件路徑2,]
files = ("\0".join(filepaths_list)).replace("/", "\\")
data = files.encode("U16")[2:] + b"\0\0"        #結尾一定要兩個\0\0字符,這是規定!

'''
對於多個文本路徑,我們如何將其轉換為我們需要的Unicode 雙字節形式呢?
首先,我們要知道Unicode編碼采用UCS-2格式直接存儲,而UTF-16恰好對應於UCS-2的,即UCS-2指定的碼位通過大端或小端的方式直接保存。UTF-16 有三種類型:UTF-16,UTF-16BE(大端序),UTF-16LE(小端序).UTF-16 通過以名稱BOM(字節順序標記,U + FEFF)啟動文件來指示該文件仍然是小端序。
我們只需要把python String使用UTF-16編碼后,去掉前兩個字節,得到相應的Unicode雙字節。
'''
win32clipboard.OpenClipboard()  #打開剪貼板(獨占)
try:
    #若要將信息放在剪貼板上,首先需要使用 EmptyClipboard 函數清除當前的剪貼板內容
    win32clipboard.EmptyClipboard() #清空當前的剪貼板信息
    win32clipboard.SetClipboardData(win32clipboard.CF_HDROP,bytes(pDropFiles)+data) #設置當前剪貼板數據
except Exception as e:
    print(str(e))
finally:
    win32clipboard.CloseClipboard() #無論什么情況,都關閉剪貼板
  1. 實現剪切文件
#這其實是一個結構體,用以記錄文件的各種信息。
        class DROPFILES(ctypes.Structure):
            _fields_ = [
                ("pFiles", ctypes.c_uint),
                ("x", ctypes.c_long),
                ("y", ctypes.c_long),
                ("fNC", ctypes.c_int),
                ("fWide", ctypes.c_bool),   #指示文件是否包含 ANSI 或 Unicode 字符。如果值為零,則文件包含 ANSI 字符。否則,它包含 Unicode 字符。
            ]

        pDropFiles = DROPFILES()
        pDropFiles.pFiles = ctypes.sizeof(DROPFILES)
        pDropFiles.fWide = True
        #獲取文件絕對路徑
        filepaths_list = []
        files = ("\0".join(filepaths_list)).replace("/", "\\")
        data = files.encode("U16")[2:] + b"\0\0"        #結尾一定要兩個\0\0字符,這是規定!就是構造NULL字符

        '''
        對於多個文本路徑,我們如何將其轉換為我們需要的Unicode 雙字節形式呢?
        首先,我們要知道Unicode編碼采用UCS-2格式直接存儲,而UTF-16恰好對應於UCS-2的,即UCS-2指定的碼位通過大端或小端的方式直接保存。UTF-16 有三種類型:UTF-16,UTF-16BE(大端序),UTF-16LE(小端序).UTF-16 通過以名稱BOM(字節順序標記,U + FEFF)啟動文件來指示該文件仍然是小端序。
        我們只需要把python String使用UTF-16編碼后,去掉前兩個字節,得到相應的Unicode雙字節。
        '''
        win32clipboard.OpenClipboard()  #打開剪貼板(獨占)
        try:
            #若要將信息放在剪貼板上,首先需要使用 EmptyClipboard 函數清除任何以前的剪貼板內容
            win32clipboard.EmptyClipboard() #清空當前的剪貼板信息,否則不能寫入

            uDropEffect = win32clipboard.RegisterClipboardFormat("Preferred DropEffect")  #注冊格式
            
            win32clipboard.SetClipboardData(win32clipboard.CF_HDROP,bytes(pDropFiles)+data) #設置當前剪貼板數據
            win32clipboard.SetClipboardData(uDropEffect,b'\x02\x00\x00\x00')  #寫入代表剪切操作的數據
            err = ctypes.windll.kernel32.GetLastError()
            if err == 0:
                self.__statusBar.config(text="剪切成功!", fg="green")
            else:
                self.__statusBar.config(text="剪切失敗!errorCode={}".format(err), fg="red")
        except Exception as e:
            exc_type, exc_value, exc_traceback_obj = sys.exc_info()
            traceback.print_tb(exc_traceback_obj)
            self.__statusBar.config(text="剪切失敗!", fg="red")
        finally:
            win32clipboard.CloseClipboard() #無論什么情況,都關閉剪貼板

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM