Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #13: we're waiting for [the phone company] to fix that line


comp / comp.lang.python / Re: win32clipboard writing to clipboard on Windows 11

SubjectAuthor
o Re: win32clipboard writing to clipboard on Windows 11Eryk Sun

1
Subject: Re: win32clipboard writing to clipboard on Windows 11
From: Eryk Sun
Newsgroups: comp.lang.python
Date: Tue, 18 Jun 2024 07:19 UTC
References: 1 2 3
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!fu-berlin.de!uni-berlin.de!not-for-mail
From: eryksun@gmail.com (Eryk Sun)
Newsgroups: comp.lang.python
Subject: Re: win32clipboard writing to clipboard on Windows 11
Date: Tue, 18 Jun 2024 02:19:09 -0500
Lines: 68
Message-ID: <mailman.151.1718695189.2909.python-list@python.org>
References: <f6e408ad-89c1-42b0-a771-d3677692f610@btinternet.com>
<7e8c9107-6f71-4c49-a78b-ac5094073499@mrabarnett.plus.com>
<CACL+1atEbLNT3E3cm+mApSAQ9xKQb1__muSFWrjajk702+ZcJw@mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Trace: news.uni-berlin.de e1pXdFBtkLR/IqeBa6XELwsUk6kJUePXnTJ34o+HqbHg==
Cancel-Lock: sha1:57bXGc02MaBhBbrkgcu3NBJzAQQ= sha256:vgeETQVhh25TJD4EsNwNlSU5UgEkl5QHX0sJ2ZxWoYU=
Return-Path: <eryksun@gmail.com>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=pass
reason="2048-bit key; unprotected key"
header.d=gmail.com header.i=@gmail.com header.b=lFJnLcyk;
dkim-adsp=pass; dkim-atps=neutral
X-Spam-Status: OK 0.003
X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; '17,': 0.04; 'argument':
0.04; 'def': 0.04; 'random': 0.05; 'string': 0.07;
'subject:Windows': 0.07; 'cc:addr:python-list': 0.09; 'example:':
0.09; 'memory.': 0.09; 'numeric': 0.09; 'subject:writing': 0.09;
'cc:no real name:2**0': 0.14; 'import': 0.15; 'memory': 0.15;
'2024': 0.16; 'conversion': 0.16; 'hand,': 0.16; 'integer': 0.16;
'owns': 0.16; 'tries': 0.16; 'wrote:': 0.16; 'cc:addr:python.org':
0.20; 'basically': 0.22; 'exception': 0.22; 'returns': 0.22;
'code': 0.23; 'cc:2**0': 0.25; 'jun': 0.26; 'it,': 0.29; 'error':
0.29; 'raise': 0.31; 'python-list': 0.32; 'window': 0.32;
'message-id:@mail.gmail.com': 0.32; 'unless': 0.32; 'header:In-
Reply-To:1': 0.34; 'received:google.com': 0.34;
'from:addr:gmail.com': 0.35; 'mon,': 0.36; 'currently': 0.37;
'using': 0.37; "it's": 0.37; 'text': 0.39; 'otherwise': 0.39;
'handle': 0.39; 'valid': 0.39; 'block': 0.39; 'skip:u 20': 0.39;
'skip:o 10': 0.61; 'copy': 0.63; 'pass': 0.64; "you'd": 0.64;
'skip:e 20': 0.67; 'manager': 0.68; 'manually': 0.69; 'global':
0.73; 'easy': 0.74; 'subject:skip:w 10': 0.76; 'skip:k 20': 0.78;
'happens': 0.84; 'peculiar': 0.84; 'rob': 0.84; 'skip:k 30': 0.84
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=20230601; t=1718695186; x=1719299986; darn=python.org;
h=content-transfer-encoding:cc:to:subject:message-id:date:from
:in-reply-to:references:mime-version:from:to:cc:subject:date
:message-id:reply-to;
bh=/Hp+vr1jT05Q6mWSD8XSSadge5dRMnfVqZz8rmdtiYA=;
b=lFJnLcykWJ4hbFJZL5ZgURyB7zxR21MfbXflc+/EHF/h+NXAEWzkOgPr3qHI+7Ig2b
w1kxJxl6ERa0RiOqlTKFAA6TGsQ3rAv3gfY4Bt4UvWArZ/wxM0dPIeFY9SFN4l2+zwGj
hNipyApeCTPCmRTXQUq/IswDuF5ccfaoFIyM5lTAS6m3LOx50t0TIG9szYsOWyLlPieo
smwM2eWd6dlmpqOE3hBT9K9jMhQENtxDc5Q+Bf/yXxRz9fFGx3RDYixzGtYIrnkDUdTa
i9nRsQ2O1Gwi+dpvMj6q2gPv0dJBH14VLb2ctDlt9W1OgoHCXxAUcD0dq6sG1vO2UMUQ
/YmQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20230601; t=1718695186; x=1719299986;
h=content-transfer-encoding:cc:to:subject:message-id:date:from
:in-reply-to:references:mime-version:x-gm-message-state:from:to:cc
:subject:date:message-id:reply-to;
bh=/Hp+vr1jT05Q6mWSD8XSSadge5dRMnfVqZz8rmdtiYA=;
b=PXRvjseHrjWC3c3i5+1SbB0sRJZySN4pJ6H+BpQzGT2cfQj7Vf31CZg6TmlIRbFG8c
QIej8bMMCTmvhXu5mJ5BDjUUyX1VMSTBoBKfBs7yV2KDKR7aWGkbHdalP1lkdCg0Eggi
09n0XGb5JwP21R9C7LVxZ4s5p6xEUvKhqoYU1q8sdZ0/H4nFHsIVnuv0z5AcU6/ziA+t
4i1v8Ld9w3phYU1aqJOwiUrkICGvub5HelB46RPCgDYerKGCUqByzsc7Ct/WYP7KvvkG
lUVy1xQXQGU1AfyfrVTWKM6JYugccegOGLjnseMq7Z1S8lGq7LxmNfEnrSG36/LNA7p5
pKrA==
X-Gm-Message-State: AOJu0YzXijLcsUQByHYEK7M3E4n62C6MPIT9zHn/TXd3W5bGk6mfALuz
awaNg+ngDIBq1JbEmhoBDhO9Jy4bXh6vhKyQCNeR4/DwY+Bh9587G6lSOnvk2edARUsO10K3LkI
itTey5GkBGhK0/7Zdixk8r/+M7yXRWEU6
X-Google-Smtp-Source: AGHT+IGMS1B66wYWl4AjkDymunF3vYS9K429GfRiiseXYOHnkbTWubCSlZ8MTP3llptT0HF8JsHze5IoWqvW969frco=
X-Received: by 2002:a05:6870:548a:b0:259:86a8:4191 with SMTP id
586e51a60fabf-25986aa4269mr242281fac.5.1718695186036; Tue, 18 Jun 2024
00:19:46 -0700 (PDT)
In-Reply-To: <7e8c9107-6f71-4c49-a78b-ac5094073499@mrabarnett.plus.com>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <CACL+1atEbLNT3E3cm+mApSAQ9xKQb1__muSFWrjajk702+ZcJw@mail.gmail.com>
X-Mailman-Original-References: <f6e408ad-89c1-42b0-a771-d3677692f610@btinternet.com>
<7e8c9107-6f71-4c49-a78b-ac5094073499@mrabarnett.plus.com>
View all headers

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)

1

rocksolid light 0.9.8
clearnet tor