mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-13 07:47:14 +03:00
prefs.py: Always use tkinter.filedialog
for Output File Location
* I can't even get this code to be problematic, with a folder containing unicode heart characters, on 64-bit Python 3.7.9 (Release/4.1.6 adjusted to not set UTF-8 locale), let alone on 64-bit Python 3.11 and this branch. So, just always use the tkinter dialog. Bye-bye ctypes code which I just couldn't get to work under 64-bit Python. * I *think* the issue with the ctypes code was that under 32-bit an 'int' and a pointer are the same size. 'Raw' (not declaring types beforehand) the `SHBrowseForFolderW()` function causes ctypes to consider it returns an int. This works on 32-bit. But on 64-bit that int is still 32-bits, but pointers are 64-bit, so ctypes ends up coercing/casting/truncating the returned pointer into an int, which than can't even be cast back to a pointer. Meanwhile, attempting to properly define the signature of the function has only lead to it crashing on invocation, despite being passed the same BROWSEINFOW structure, defined in the same manner. This might be a matter of a type within it needing adjusting, but I was following the docs there.
This commit is contained in:
parent
da530f135e
commit
09ecdbb849
49
prefs.py
49
prefs.py
@ -1078,48 +1078,13 @@ class PreferencesDialog(tk.Toplevel):
|
||||
:param title: Title of the window
|
||||
:param pathvar: the path to start the dialog on
|
||||
"""
|
||||
import locale
|
||||
|
||||
# If encoding isn't UTF-8 we can't use the tkinter dialog
|
||||
current_locale = locale.getlocale(locale.LC_CTYPE)
|
||||
directory = None
|
||||
if sys.platform == 'win32' and current_locale[1] not in ('utf8', 'UTF8', 'utf-8', 'UTF-8'):
|
||||
def browsecallback(hwnd, uMsg, lParam, lpData): # noqa: N803 # Windows API convention
|
||||
# set initial folder
|
||||
if uMsg == BFFM_INITIALIZED and lpData:
|
||||
ctypes.windll.user32.SendMessageW(hwnd, BFFM_SETSELECTION, 1, lpData)
|
||||
return 0
|
||||
|
||||
browseInfo = BROWSEINFOW() # noqa: N806 # Windows convention
|
||||
# browseInfo.pidlRoot = None
|
||||
browseInfo.pszDisplayName = ctypes.c_wchar_p("x" * MAX_PATH)
|
||||
browseInfo.lpszTitle = title
|
||||
browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI
|
||||
browseInfo.lpfn = BrowseCallbackProc(browsecallback)
|
||||
# browseInfo.lParam = pathvar.get().startswith('~') and join(config.home_path,
|
||||
# pathvar.get()[2:]) or pathvar.get()
|
||||
ctypes.windll.ole32.CoInitialize(None)
|
||||
pidl = ctypes.windll.shell32.SHBrowseForFolderW(ctypes.byref(browseInfo))
|
||||
# ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP__ITEMIDLIST instance instead of int
|
||||
# pidl = SHBrowseForFolderW(ctypes.byref(browseInfo))
|
||||
# OSError: exception: access violation writing 0x00007FFB582DC9BF
|
||||
if pidl:
|
||||
pidl = ctypes.cast(pidl, PIDLIST_ABSOLUTE)
|
||||
path = ctypes.create_unicode_buffer(MAX_PATH)
|
||||
path = SHGetPathFromIDListW(pidl)
|
||||
ctypes.windll.ole32.CoTaskMemFree(pidl)
|
||||
directory = path.value
|
||||
else:
|
||||
directory = None
|
||||
|
||||
else:
|
||||
import tkinter.filedialog
|
||||
directory = tkinter.filedialog.askdirectory(
|
||||
parent=self,
|
||||
initialdir=expanduser(pathvar.get()),
|
||||
title=title,
|
||||
mustexist=tk.TRUE
|
||||
)
|
||||
import tkinter.filedialog
|
||||
directory = tkinter.filedialog.askdirectory(
|
||||
parent=self,
|
||||
initialdir=expanduser(pathvar.get()),
|
||||
title=title,
|
||||
mustexist=tk.TRUE
|
||||
)
|
||||
|
||||
if directory:
|
||||
pathvar.set(directory)
|
||||
|
Loading…
x
Reference in New Issue
Block a user