mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-12 23:37:14 +03:00
Merge pull request #1703 from EDCD/enhancement/64-bit
Make runnable under 64-bit Python
This commit is contained in:
commit
7e6f3251bb
2
.github/workflows/windows-build.yml
vendored
2
.github/workflows/windows-build.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
run: |
|
||||
Invoke-Webrequest -UseBasicParsing https://github.com/vslavik/winsparkle/releases/download/v0.7.0/WinSparkle-0.7.0.zip -OutFile out.zip
|
||||
Expand-Archive out.zip
|
||||
Move-Item 'out\WinSparkle-0.7.0\Release\*' '.\'
|
||||
Move-Item 'out\WinSparkle-0.7.0\x64\Release\*' '.\'
|
||||
|
||||
- name: Build EDMC
|
||||
run: |
|
||||
|
@ -2,7 +2,6 @@
|
||||
"""Build to executables and MSI installer using py2exe and other tools."""
|
||||
import os
|
||||
import pathlib
|
||||
import platform
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
@ -22,7 +21,6 @@ if sys.version_info[0:2] != (3, 11):
|
||||
raise AssertionError(f'Unexpected python version {sys.version}')
|
||||
|
||||
if sys.platform == 'win32':
|
||||
assert platform.architecture()[0] == '32bit', 'A Python 32bit build is required'
|
||||
import py2exe # noqa: F401 # Yes, this *is* used
|
||||
dist_dir = 'dist.win32'
|
||||
|
||||
|
60
prefs.py
60
prefs.py
@ -181,7 +181,7 @@ if sys.platform == 'darwin':
|
||||
elif sys.platform == 'win32':
|
||||
import ctypes
|
||||
import winreg
|
||||
from ctypes.wintypes import HINSTANCE, HWND, LPARAM, LPCWSTR, LPVOID, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT
|
||||
from ctypes.wintypes import HINSTANCE, HWND, LPCWSTR, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT
|
||||
is_wine = False
|
||||
try:
|
||||
WINE_REGISTRY_KEY = r'HKEY_LOCAL_MACHINE\Software\Wine'
|
||||
@ -189,22 +189,9 @@ elif sys.platform == 'win32':
|
||||
winreg.OpenKey(reg, WINE_REGISTRY_KEY)
|
||||
is_wine = True
|
||||
|
||||
except OSError:
|
||||
except OSError: # Assumed to be 'path not found', i.e. not-wine
|
||||
pass
|
||||
|
||||
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb762115
|
||||
BIF_RETURNONLYFSDIRS = 0x00000001
|
||||
BIF_USENEWUI = 0x00000050
|
||||
BFFM_INITIALIZED = 1
|
||||
BFFM_SETSELECTION = 0x00000467
|
||||
BrowseCallbackProc = ctypes.WINFUNCTYPE(ctypes.c_int, HWND, ctypes.c_uint, LPARAM, LPARAM)
|
||||
|
||||
class BROWSEINFO(ctypes.Structure):
|
||||
"""Windows file browser fields."""
|
||||
|
||||
_fields_ = [("hwndOwner", HWND), ("pidlRoot", LPVOID), ("pszDisplayName", LPWSTR), ("lpszTitle", LPCWSTR),
|
||||
("ulFlags", UINT), ("lpfn", BrowseCallbackProc), ("lParam", LPCWSTR), ("iImage", ctypes.c_int)]
|
||||
|
||||
CalculatePopupWindowPosition = None
|
||||
if not is_wine:
|
||||
try:
|
||||
@ -1044,42 +1031,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 = BROWSEINFO() # noqa: N806 # Windows convention
|
||||
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))
|
||||
if pidl:
|
||||
path = ctypes.create_unicode_buffer(MAX_PATH)
|
||||
ctypes.windll.shell32.SHGetPathFromIDListW(pidl, path)
|
||||
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)
|
||||
|
37
protocol.py
37
protocol.py
@ -106,12 +106,12 @@ if sys.platform == 'darwin' and getattr(sys, 'frozen', False): # noqa: C901 # i
|
||||
|
||||
def handleEvent_withReplyEvent_(self, event, replyEvent) -> None: # noqa: N802 N803 # Required to override
|
||||
"""Actual event handling from NSAppleEventManager."""
|
||||
protocolhandler.lasturl = urllib.parse.unquote( # noqa: F821: type: ignore # Its going to be a DPH in
|
||||
protocolhandler.lasturl = urllib.parse.unquote( # noqa: F821: type: ignore # It's going to be a DPH in
|
||||
# this code
|
||||
event.paramDescriptorForKeyword_(keyDirectObject).stringValue()
|
||||
).strip()
|
||||
|
||||
protocolhandler.master.after(DarwinProtocolHandler.POLL, protocolhandler.poll) # noqa: F821: type: ignore
|
||||
protocolhandler.master.after(DarwinProtocolHandler.POLL, protocolhandler.poll) # noqa: F821 # type: ignore
|
||||
|
||||
|
||||
elif (config.auth_force_edmc_protocol
|
||||
@ -129,8 +129,8 @@ elif (config.auth_force_edmc_protocol
|
||||
POINTER, WINFUNCTYPE, Structure, byref, c_long, c_void_p, create_unicode_buffer, wstring_at
|
||||
)
|
||||
from ctypes.wintypes import (
|
||||
ATOM, BOOL, DWORD, HBRUSH, HGLOBAL, HICON, HINSTANCE, HMENU, HWND, INT, LPARAM, LPCWSTR, LPVOID, LPWSTR, MSG,
|
||||
UINT, WPARAM
|
||||
ATOM, BOOL, DWORD, HBRUSH, HGLOBAL, HICON, HINSTANCE, HMENU, HWND, INT, LPARAM, LPCWSTR, LPMSG, LPVOID, LPWSTR,
|
||||
MSG, UINT, WPARAM
|
||||
)
|
||||
|
||||
class WNDCLASS(Structure):
|
||||
@ -161,11 +161,25 @@ elif (config.auth_force_edmc_protocol
|
||||
CreateWindowExW.restype = HWND
|
||||
RegisterClassW = windll.user32.RegisterClassW
|
||||
RegisterClassW.argtypes = [POINTER(WNDCLASS)]
|
||||
DefWindowProcW = windll.user32.DefWindowProcW
|
||||
# DefWindowProcW
|
||||
# Ref: <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowprocw>
|
||||
# LRESULT DefWindowProcW([in] HWND hWnd,[in] UINT Msg,[in] WPARAM wParam,[in] LPARAM lParam);
|
||||
# As per example at <https://docs.python.org/3/library/ctypes.html#ctypes.WINFUNCTYPE>
|
||||
|
||||
prototype = WINFUNCTYPE(c_long, HWND, UINT, WPARAM, LPARAM)
|
||||
paramflags = (1, "hWnd"), (1, "Msg"), (1, "wParam"), (1, "lParam")
|
||||
DefWindowProcW = prototype(("DefWindowProcW", windll.user32), paramflags)
|
||||
|
||||
GetParent = windll.user32.GetParent
|
||||
SetForegroundWindow = windll.user32.SetForegroundWindow
|
||||
|
||||
GetMessageW = windll.user32.GetMessageW
|
||||
# <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagew>
|
||||
# NB: Despite 'BOOL' return type, it *can* be >0, 0 or -1, so is actually
|
||||
# c_long
|
||||
prototype = WINFUNCTYPE(c_long, LPMSG, HWND, UINT, UINT)
|
||||
paramflags = (1, "lpMsg"), (1, "hWnd"), (1, "wMsgFilterMin"), (1, "wMsgFilterMax")
|
||||
GetMessageW = prototype(("GetMessageW", windll.user32), paramflags)
|
||||
|
||||
TranslateMessage = windll.user32.TranslateMessage
|
||||
DispatchMessageW = windll.user32.DispatchMessageW
|
||||
PostThreadMessageW = windll.user32.PostThreadMessageW
|
||||
@ -307,6 +321,17 @@ elif (config.auth_force_edmc_protocol
|
||||
|
||||
msg = MSG()
|
||||
# Calls GetMessageW: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagew
|
||||
# Something is off with the return from this, meaning you'll see:
|
||||
# Exception ignored on converting result of ctypes callback function: <function WndProc
|
||||
# at 0x000001F5B8738FE0>
|
||||
# Traceback (most recent call last):
|
||||
# File "C:\Users\Athan\Documents\Devel\EDMarketConnector\protocol.py", line 323, in worker
|
||||
# while int(GetMessageW(byref(msg), None, 0, 0)) != 0:
|
||||
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
# TypeError: 'c_long' object cannot be interpreted as an integer
|
||||
#
|
||||
# But it does actually work. Either getting a non-0 value and
|
||||
# entering the loop, or getting 0 and exiting it.
|
||||
while GetMessageW(byref(msg), None, 0, 0) != 0:
|
||||
logger.trace_if('frontier-auth.windows', f'DDE message of type: {msg.message}')
|
||||
if msg.message == WM_DDE_EXECUTE:
|
||||
|
Loading…
x
Reference in New Issue
Block a user