Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

apply_dnd() doesn't work correctly with paths that contain Unicode characters #42

Open
Valer100 opened this issue Oct 27, 2024 · 1 comment

Comments

@Valer100
Copy link

Valer100 commented Oct 27, 2024

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:

Screen.Recording.2024-10-27.153646.mp4

The folder's name that included Unicode characters: ăâîșț

Windows 11 23H2 (Build 22631.4391)
Python 3.11.9
pywinstyles 1.8

@B16f00t
Copy link

B16f00t commented Jan 25, 2025

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))
        )

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants