py-window-styles
py-window-styles copied to clipboard
`apply_dnd()` doesn't work correctly with paths that contain Unicode characters
When I try to drag and drop a file or a folder that has Unicode characters in their path, apply_dnd() will throw a UnicodeDecodeError. Here's the full exception message:
Exception ignored on calling ctypes callback function: <function apply_dnd.__init__.<locals>.py_drop_func at 0x0000026A686B23E0>
Traceback (most recent call last):
File "C:\Program Files\Python311\Lib\site-packages\pywinstyles\py_win_style.py", line 205, in py_drop_func
drop_name = file_buffer.value.decode("utf-8")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 25: invalid continuation byte
Minimal reproducible example:
import tkinter, pywinstyles
from tkinter import messagebox
window = tkinter.Tk()
def print_dnd_paths(file): print(file)
pywinstyles.apply_dnd(window, print_dnd_paths)
window.mainloop()
Here's a screen recording:
https://github.com/user-attachments/assets/b3199fc0-9848-4a6d-bb44-f26f0d8b96e5
The folder's name that included Unicode characters: ăâîșț
Windows 11 23H2 (Build 22631.4391) Python 3.11.9 pywinstyles 1.8
You can fix the issue in this way:
def py_drop_func(hwnd, msg, wp, lp):
global files
if msg == WM_DROP_FILES:
count = func_DragQueryFile(typ(wp), -1, None, None)
file_buffer = create_buffer(char_limit)
files = []
for i in range(count):
func_DragQueryFile(typ(wp), i, file_buffer, sizeof(file_buffer))
try:
drop_name = file_buffer.value.decode("utf-8")
except UnicodeDecodeError:
# If UTF-8 decoding fails, attempt to decode with a different encoding (e.g., Windows-1252)
drop_name = file_buffer.value.decode("Windows-1252")
files.append(drop_name)
func(files)
windll.shell32.DragFinish(typ(wp))
return windll.user32.CallWindowProcW(
*map(typ, (globals()[old], hwnd, msg, wp, lp))
)