Re: win32clipboard writing to clipboard on Windows 11

Liste des GroupesRevenir à cl python 
Sujet : Re: win32clipboard writing to clipboard on Windows 11
De : eryksun (at) *nospam* gmail.com (Eryk Sun)
Groupes : comp.lang.python
Date : 18. Jun 2024, 08:19:09
Autres entêtes
Message-ID : <mailman.151.1718695189.2909.python-list@python.org>
References : 1 2 3
On Mon, Jun 17, 2024 at 8:36 PM MRAB via Python-list
<python-list@python.org> wrote:
On 2024-06-17 20:27, Rob Cliffe via Python-list wrote:
>
SetClipboardData(CF_UNICODETEXT, "0")
CloseClipboard()

win32clipboard.SetClipboardData() first tries to covert the second
argument as an integer handle to global memory, which gets passed to
WinAPI SetClipboardData(). The integer conversion is basically via
int(). With int("0"), it's passing a NULL handle value, which
instructs the window manager to query the data from the window that
was associated via OpenClipboard(), if any. Since no memory handle is
passed in this case, SetClipboardData() returns NULL.
win32clipboard.SetClipboardData() misinterprets this as failure and
raises an exception for whatever random error code is currently set in
the thread's last error value. On the other hand, for a numeric text
string with a nonzero value, such as "123",
win32clipboard.SetClipboardData() will raise an exception for the
error code ERROR_INVALID_HANDLE (6), unless the integer value happens
to be a valid global memory handle value.

I recommend just using win32clipboard.SetClipboardText(). Otherwise I
don't see an easy workaround given the peculiar design of
win32clipboard.SetClipboardData(). You'd have to manually allocate a
block of global memory, copy the numeric text string into it, and pass
the global memory handle to win32clipboard.SetClipboardData(). For
example:

    import ctypes
    import win32clipboard
    from ctypes import wintypes

    kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

    GMEM_MOVEABLE = 0x0002

    kernel32.GlobalAlloc.restype = wintypes.HGLOBAL
    kernel32.GlobalFree.argtypes = (wintypes.HGLOBAL,)
    kernel32.GlobalLock.restype = wintypes.LPVOID
    kernel32.GlobalLock.argtypes = (wintypes.HGLOBAL,)
    kernel32.GlobalUnlock.argtypes = (wintypes.HGLOBAL,)

    def global_alloc_text(text):
        array_t = ctypes.c_wchar * (len(text) + 1)
        hMem = kernel32.GlobalAlloc(GMEM_MOVEABLE, ctypes.sizeof(array_t))
        if not hMem:
            raise ctypes.WinError(ctypes.get_last_error())
        pMem = kernel32.GlobalLock(hMem)
        try:
            try:
                array_t.from_address(pMem).value = text
            finally:
                kernel32.GlobalUnlock(hMem)
        except:
            kernel32.GlobalFree(hMem)
            raise
        return hMem

    def set_clipboard_text(text):
        hMem = global_alloc_text(text)
        try:
            win32clipboard.SetClipboardData(win32clipboard.CF_UNICODETEXT,
                                            hMem)
            # Now the system owns the global memory.
        except:
            kernel32.GlobalFree(hMem)

Date Sujet#  Auteur
18 Jun 24 o Re: win32clipboard writing to clipboard on Windows 111Eryk Sun

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal