使用 python 中的 ctypes 读取不同类型的剪贴板数据

Read different types of clipboard data with ctypes in python

我有这段代码,它使用 GetClipboardData 函数中的 CF_UNICODETEXT 获取 windows 剪贴板数据(文本)和 ctypes。

from __future__ import print_function
import ctypes
import ctypes.wintypes as w

CF_UNICODETEXT = 13
CF_HDROP = 15

u32 = ctypes.windll.user32
k32 = ctypes.windll.kernel32

OpenClipboard = u32.OpenClipboard
OpenClipboard.argtypes = w.HWND,
OpenClipboard.restype = w.BOOL
GetClipboardData = u32.GetClipboardData
GetClipboardData.argtypes = w.UINT,
GetClipboardData.restype = w.HANDLE
GlobalLock = k32.GlobalLock
GlobalLock.argtypes = w.HGLOBAL,
GlobalLock.restype = w.LPVOID
GlobalUnlock = k32.GlobalUnlock
GlobalUnlock.argtypes = w.HGLOBAL,
GlobalUnlock.restype = w.BOOL
CloseClipboard = u32.CloseClipboard
CloseClipboard.argtypes = None
CloseClipboard.restype = w.BOOL


def get_clipboard_text():
    text = ""
    if OpenClipboard(None):
        h_clip_mem = GetClipboardData(CF_UNICODETEXT)
        text = ctypes.wstring_at(GlobalLock(h_clip_mem))
        GlobalUnlock(h_clip_mem)
        CloseClipboard()
    return text


print(get_clipboard_text())

CF_HDROP 应该是 return 复制到剪贴板的文件列表, (https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats) 但我无法让它工作。

如何将此代码添加到 return 文件列表而不仅仅是文本?

如果 CF_HDROP 格式可用,您可以使用 DragQueryFile() 首先告诉您有多少文件存在。然后你可以为每个条目调用一次以获取文件名。例如:

import sys
import ctypes
import ctypes.wintypes as w

CF_HDROP = 15

u32 = ctypes.windll.user32
k32 = ctypes.windll.kernel32
s32 = ctypes.windll.shell32

OpenClipboard = u32.OpenClipboard
OpenClipboard.argtypes = w.HWND,
OpenClipboard.restype = w.BOOL

GetClipboardData = u32.GetClipboardData
GetClipboardData.argtypes = w.UINT,
GetClipboardData.restype = w.HANDLE

CloseClipboard = u32.CloseClipboard
CloseClipboard.argtypes = None
CloseClipboard.restype = w.BOOL

DragQueryFile = s32.DragQueryFile
DragQueryFile.argtypes = [w.HANDLE, w.UINT, ctypes.c_void_p, w.UINT]


def get_file_list():
    files = []
    
    if OpenClipboard(None):
        h_hdrop = GetClipboardData(CF_HDROP)
        
        if h_hdrop:
            FS_ENCODING = sys.getfilesystemencoding()
            file_count = DragQueryFile(h_hdrop, -1, None, 0)

            for index in range(file_count):
                buf = ctypes.c_buffer(260)
                DragQueryFile(h_hdrop, index, buf, ctypes.sizeof(buf))
                files.append(buf.value.decode(FS_ENCODING))

    CloseClipboard()
    return files
    
print(get_file_list())

因此,如果您现在 select Windows 资源管理器中的一些文件并使用 Copy,脚本应该 return 文件列表。