Skip to content

Commit 625856c

Browse files
committed
[1805] Apply More Pywin32
1 parent 571558d commit 625856c

6 files changed

+34
-81
lines changed

EDMarketConnector.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,6 @@ def handle_edmc_callback_or_foregrounding() -> None: # noqa: CCR001
263263
import win32con
264264

265265
GetProcessHandleFromHwnd = windll.oleacc.GetProcessHandleFromHwnd # noqa: N806
266-
267-
ShowWindow = windll.user32.ShowWindow # noqa: N806
268266
ShowWindowAsync = windll.user32.ShowWindowAsync # noqa: N806
269267

270268
COINIT_MULTITHREADED = 0 # noqa: N806,F841
@@ -308,7 +306,7 @@ def enumwindowsproc(window_handle, l_param): # noqa: CCR001
308306
if len(sys.argv) > 1 and sys.argv[1].startswith(protocolhandler_redirect):
309307
CoInitializeEx(0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE)
310308
# Wait for it to be responsive to avoid ShellExecute recursing
311-
ShowWindow(window_handle, win32con.SW_RESTORE)
309+
win32gui.ShowWindow(window_handle, win32con.SW_RESTORE)
312310
win32api.ShellExecute(0, None, sys.argv[1], None, None, win32con.SW_RESTORE)
313311

314312
else:

monitor.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,15 @@
3636

3737
if sys.platform == 'win32':
3838
import ctypes
39-
from ctypes.wintypes import BOOL, HWND, LPARAM, HANDLE
39+
from ctypes.wintypes import BOOL, HWND, LPARAM
4040
import win32gui
41+
import win32api
4142

4243
from watchdog.events import FileSystemEventHandler, FileSystemEvent
4344
from watchdog.observers import Observer
4445
from watchdog.observers.api import BaseObserver
4546

4647
EnumWindowsProc = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
47-
CloseHandle = ctypes.windll.kernel32.CloseHandle
48-
CloseHandle.argtypes = [HANDLE]
49-
CloseHandle.restype = BOOL
5048
GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd
5149

5250
else:
@@ -2136,7 +2134,7 @@ def callback(hWnd, lParam): # noqa: N803
21362134
if name and name.startswith('Elite - Dangerous'):
21372135
handle = GetProcessHandleFromHwnd(hWnd)
21382136
if handle: # If GetProcessHandleFromHwnd succeeds then the app is already running as this user
2139-
CloseHandle(handle)
2137+
win32api.CloseHandle(handle)
21402138
return False # stop enumeration
21412139

21422140
return True

prefs.py

+4-7
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,9 @@ def __exit__(
188188
if sys.platform == 'win32':
189189
import ctypes
190190
import winreg
191-
from ctypes.wintypes import HINSTANCE, LPCWSTR, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT, BOOL
191+
from ctypes.wintypes import LPCWSTR, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT, BOOL
192192
import win32gui
193+
import win32api
193194
is_wine = False
194195
try:
195196
WINE_REGISTRY_KEY = r'HKEY_LOCAL_MACHINE\Software\Wine'
@@ -225,10 +226,6 @@ def __exit__(
225226
SHGetLocalizedName = ctypes.windll.shell32.SHGetLocalizedName
226227
SHGetLocalizedName.argtypes = [LPCWSTR, LPWSTR, UINT, ctypes.POINTER(ctypes.c_int)]
227228

228-
LoadString = ctypes.windll.user32.LoadStringW
229-
LoadString.argtypes = [HINSTANCE, UINT, LPWSTR, ctypes.c_int]
230-
LoadString.restype = ctypes.c_int
231-
232229

233230
class PreferencesDialog(tk.Toplevel):
234231
"""The EDMC preferences dialog."""
@@ -313,7 +310,7 @@ def __init__(self, parent: tk.Tk, callback: Optional[Callable]):
313310
# Ensure fully on-screen
314311
if sys.platform == 'win32' and CalculatePopupWindowPosition:
315312
position = RECT()
316-
win32gui.GetWindowRect(win32gui.GetParent(self.winfo_id()), position)
313+
win32gui.GetWindowRect(win32gui.GetParent(self.winfo_id()))
317314
if CalculatePopupWindowPosition(
318315
POINT(parent.winfo_rootx(), parent.winfo_rooty()),
319316
SIZE(position.right - position.left, position.bottom - position.top), # type: ignore
@@ -1093,7 +1090,7 @@ def displaypath(self, pathvar: tk.StringVar, entryfield: tk.Entry) -> None:
10931090
for i in range(start, len(components)):
10941091
try:
10951092
if (not SHGetLocalizedName('\\'.join(components[:i+1]), buf, MAX_PATH, ctypes.byref(pidsRes)) and
1096-
LoadString(ctypes.WinDLL(expandvars(buf.value))._handle, pidsRes.value, buf, MAX_PATH)):
1093+
win32api.LoadString(ctypes.WinDLL(expandvars(buf.value))._handle, pidsRes.value, buf, MAX_PATH)):
10971094
display.append(buf.value)
10981095

10991096
else:

protocol.py

+20-55
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,16 @@ def event(self, url: str) -> None:
6969
# This could be false if you use auth_force_edmc_protocol, but then you get to keep the pieces
7070
assert sys.platform == 'win32'
7171
# spell-checker: words HBRUSH HICON WPARAM wstring WNDCLASS HMENU HGLOBAL
72-
from ctypes import ( # type: ignore
73-
windll, POINTER, WINFUNCTYPE, Structure, byref, c_long, c_void_p, create_unicode_buffer, wstring_at
72+
from ctypes import (
73+
windll, WINFUNCTYPE, Structure, byref, c_long, c_void_p, create_unicode_buffer, wstring_at
7474
)
7575
from ctypes.wintypes import (
76-
ATOM, BOOL, DWORD, HBRUSH, HGLOBAL, HICON, HINSTANCE, HMENU, HWND, INT, LPARAM, LPCWSTR, LPMSG, LPVOID, LPWSTR,
76+
ATOM, HBRUSH, HICON, HINSTANCE, HWND, INT, LPARAM, LPCWSTR, LPWSTR,
7777
MSG, UINT, WPARAM
7878
)
79-
from win32con import CW_USEDEFAULT
8079
import win32gui
8180
import win32con
81+
import win32api
8282

8383
class WNDCLASS(Structure):
8484
"""
@@ -101,37 +101,7 @@ class WNDCLASS(Structure):
101101
('lpszClassName', LPCWSTR)
102102
]
103103

104-
105-
CreateWindowExW = windll.user32.CreateWindowExW
106-
CreateWindowExW.argtypes = [DWORD, LPCWSTR, LPCWSTR, DWORD, INT, INT, INT, INT, HWND, HMENU, HINSTANCE, LPVOID]
107-
CreateWindowExW.restype = HWND
108-
RegisterClassW = windll.user32.RegisterClassW
109-
RegisterClassW.argtypes = [POINTER(WNDCLASS)]
110-
# DefWindowProcW
111-
# Ref: <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowprocw>
112-
# LRESULT DefWindowProcW([in] HWND hWnd,[in] UINT Msg,[in] WPARAM wParam,[in] LPARAM lParam);
113-
# As per example at <https://docs.python.org/3/library/ctypes.html#ctypes.WINFUNCTYPE>
114-
115-
prototype = WINFUNCTYPE(c_long, HWND, UINT, WPARAM, LPARAM)
116-
paramflags = (1, "hWnd"), (1, "Msg"), (1, "wParam"), (1, "lParam")
117-
DefWindowProcW = prototype(("DefWindowProcW", windll.user32), paramflags)
118-
119-
SetForegroundWindow = windll.user32.SetForegroundWindow
120-
121-
# <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagew>
122-
# NB: Despite 'BOOL' return type, it *can* be >0, 0 or -1, so is actually
123-
# c_long
124-
prototype = WINFUNCTYPE(c_long, LPMSG, HWND, UINT, UINT)
125-
paramflags = (1, "lpMsg"), (1, "hWnd"), (1, "wMsgFilterMin"), (1, "wMsgFilterMax")
126-
GetMessageW = prototype(("GetMessageW", windll.user32), paramflags)
127-
128104
TranslateMessage = windll.user32.TranslateMessage
129-
DispatchMessageW = windll.user32.DispatchMessageW
130-
PostThreadMessageW = windll.user32.PostThreadMessageW
131-
SendMessageW = windll.user32.SendMessageW
132-
SendMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
133-
PostMessageW = windll.user32.PostMessageW
134-
PostMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM]
135105

136106
# https://docs.microsoft.com/en-us/windows/win32/dataxchg/wm-dde-initiate
137107
WM_DDE_INITIATE = 0x03E0
@@ -148,12 +118,6 @@ class WNDCLASS(Structure):
148118
GlobalGetAtomNameW = windll.kernel32.GlobalGetAtomNameW
149119
GlobalGetAtomNameW.argtypes = [ATOM, LPWSTR, INT]
150120
GlobalGetAtomNameW.restype = UINT
151-
GlobalLock = windll.kernel32.GlobalLock
152-
GlobalLock.argtypes = [HGLOBAL]
153-
GlobalLock.restype = LPVOID
154-
GlobalUnlock = windll.kernel32.GlobalUnlock
155-
GlobalUnlock.argtypes = [HGLOBAL]
156-
GlobalUnlock.restype = BOOL
157121

158122
# Windows Message handler stuff (IPC)
159123
# https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms633573(v=vs.85)
@@ -171,7 +135,7 @@ def WndProc(hwnd: HWND, message: UINT, wParam: WPARAM, lParam: LPARAM) -> c_long
171135
if message != WM_DDE_INITIATE:
172136
# Not a DDE init message, bail and tell windows to do the default
173137
# https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowproca?redirectedfrom=MSDN
174-
return DefWindowProcW(hwnd, message, wParam, lParam)
138+
return win32gui.DefWindowProc(hwnd, message, wParam, lParam)
175139

176140
service = create_unicode_buffer(256)
177141
topic = create_unicode_buffer(256)
@@ -196,7 +160,7 @@ def WndProc(hwnd: HWND, message: UINT, wParam: WPARAM, lParam: LPARAM) -> c_long
196160

197161
if target_is_valid and topic_is_valid:
198162
# if everything is happy, send an acknowledgement of the DDE request
199-
SendMessageW(
163+
win32gui.SendMessage(
200164
wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, GlobalAddAtomW(appname), GlobalAddAtomW('System'))
201165
)
202166

@@ -229,7 +193,7 @@ def close(self) -> None:
229193
thread = self.thread
230194
if thread:
231195
self.thread = None
232-
PostThreadMessageW(thread.ident, win32con.WM_QUIT, 0, 0)
196+
win32api.PostThreadMessage(thread.ident, win32con.WM_QUIT, 0, 0)
233197
thread.join() # Wait for it to quit
234198

235199
def worker(self) -> None:
@@ -239,24 +203,25 @@ def worker(self) -> None:
239203
wndclass.lpfnWndProc = WndProc
240204
wndclass.cbClsExtra = 0
241205
wndclass.cbWndExtra = 0
242-
wndclass.hInstance = windll.kernel32.GetModuleHandleW(0)
206+
wndclass.hInstance = win32gui.GetModuleHandle(0)
243207
wndclass.hIcon = None
244208
wndclass.hCursor = None
245209
wndclass.hbrBackground = None
246210
wndclass.lpszMenuName = None
247211
wndclass.lpszClassName = 'DDEServer'
248212

249-
if not RegisterClassW(byref(wndclass)):
213+
if not win32gui.RegisterClass(byref(wndclass)):
250214
print('Failed to register Dynamic Data Exchange for cAPI')
251215
return
252216

253217
# https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-createwindowexw
254-
hwnd = CreateWindowExW(
218+
hwnd = win32gui.CreateWindowEx(
255219
0, # dwExStyle
256220
wndclass.lpszClassName, # lpClassName
257221
"DDE Server", # lpWindowName
258222
0, # dwStyle
259-
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, # X, Y, nWidth, nHeight
223+
# X, Y, nWidth, nHeight
224+
win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,
260225
self.master.winfo_id(), # hWndParent # Don't use HWND_MESSAGE since the window won't get DDE broadcasts
261226
None, # hMenu
262227
wndclass.hInstance, # hInstance
@@ -276,13 +241,13 @@ def worker(self) -> None:
276241
#
277242
# But it does actually work. Either getting a non-0 value and
278243
# entering the loop, or getting 0 and exiting it.
279-
while GetMessageW(byref(msg), None, 0, 0) != 0:
244+
while win32gui.GetMessage(byref(msg), None, 0, 0) != 0:
280245
logger.trace_if('frontier-auth.windows', f'DDE message of type: {msg.message}')
281246
if msg.message == WM_DDE_EXECUTE:
282247
# GlobalLock does some sort of "please dont move this?"
283248
# https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globallock
284-
args = wstring_at(GlobalLock(msg.lParam)).strip()
285-
GlobalUnlock(msg.lParam) # Unlocks the GlobalLock-ed object
249+
args = wstring_at(win32gui.GlobalLock(msg.lParam)).strip()
250+
win32gui.GlobalUnlock(msg.lParam) # Unlocks the GlobalLock-ed object
286251

287252
if args.lower().startswith('open("') and args.endswith('")'):
288253
logger.trace_if('frontier-auth.windows', f'args are: {args}')
@@ -291,20 +256,20 @@ def worker(self) -> None:
291256
logger.debug(f'Message starts with {self.redirect}')
292257
self.event(url)
293258

294-
SetForegroundWindow(win32gui.GetParent(self.master.winfo_id())) # raise app window
259+
win32gui.SetForegroundWindow(win32gui.GetParent(self.master.winfo_id())) # raise app window
295260
# Send back a WM_DDE_ACK. this is _required_ with WM_DDE_EXECUTE
296-
PostMessageW(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0x80, msg.lParam))
261+
win32gui.PostMessage(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0x80, msg.lParam))
297262

298263
else:
299264
# Send back a WM_DDE_ACK. this is _required_ with WM_DDE_EXECUTE
300-
PostMessageW(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0, msg.lParam))
265+
win32gui.PostMessage(msg.wParam, WM_DDE_ACK, hwnd, PackDDElParam(WM_DDE_ACK, 0, msg.lParam))
301266

302267
elif msg.message == WM_DDE_TERMINATE:
303-
PostMessageW(msg.wParam, WM_DDE_TERMINATE, hwnd, 0)
268+
win32gui.PostMessage(msg.wParam, WM_DDE_TERMINATE, hwnd, 0)
304269

305270
else:
306271
TranslateMessage(byref(msg)) # "Translates virtual key messages into character messages" ???
307-
DispatchMessageW(byref(msg))
272+
win32gui.DispatchMessage(byref(msg))
308273

309274

310275
else: # Linux / Run from source

stats.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ def __init__(self, parent: tk.Tk, data: dict[str, Any]) -> None:
420420
# Ensure fully on-screen
421421
if sys.platform == 'win32' and CalculatePopupWindowPosition:
422422
position = RECT()
423-
win32gui.GetWindowRect(win32gui.GetParent(self.winfo_id()), position)
423+
win32gui.GetWindowRect(win32gui.GetParent(self.winfo_id()))
424424
if CalculatePopupWindowPosition(
425425
POINT(parent.winfo_rootx(), parent.winfo_rooty()),
426426
# - is evidently supported on the C side

theme.py

+5-10
Original file line numberDiff line numberDiff line change
@@ -422,12 +422,7 @@ def apply(self, root: tk.Tk) -> None: # noqa: CCR001, C901
422422
self.active = theme
423423

424424
if sys.platform == 'win32':
425-
GWL_STYLE = -16 # noqa: N806 # ctypes
426-
WS_MAXIMIZEBOX = 0x00010000 # noqa: N806 # ctypes
427-
# tk8.5.9/win/tkWinWm.c:342
428-
GWL_EXSTYLE = -20 # noqa: N806 # ctypes
429-
WS_EX_APPWINDOW = 0x00040000 # noqa: N806 # ctypes
430-
WS_EX_LAYERED = 0x00080000 # noqa: N806 # ctypes
425+
import win32con
431426

432427
# FIXME: Lose the "treat this like a boolean" bullshit
433428
if theme == self.THEME_DEFAULT:
@@ -445,14 +440,14 @@ def apply(self, root: tk.Tk) -> None: # noqa: CCR001, C901
445440
root.withdraw()
446441
root.update_idletasks() # Size and windows styles get recalculated here
447442
hwnd = win32gui.GetParent(root.winfo_id())
448-
win32gui.SetWindowLong(hwnd, GWL_STYLE,
449-
win32gui.GetWindowLong(hwnd, GWL_STYLE) & ~WS_MAXIMIZEBOX) # disable maximize
443+
win32gui.SetWindowLong(hwnd, win32con.GWL_STYLE,
444+
win32gui.GetWindowLong(hwnd, win32con.GWL_STYLE) & ~win32con.WS_MAXIMIZEBOX) # disable maximize
450445

451446
if theme == self.THEME_TRANSPARENT:
452-
win32gui.SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_LAYERED) # Add to taskbar
447+
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, win32con.WS_EX_APPWINDOW | win32con.WS_EX_LAYERED) # Add to taskbar
453448

454449
else:
455-
win32gui.SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW) # Add to taskbar
450+
win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, win32con.WS_EX_APPWINDOW) # Add to taskbar
456451

457452
root.deiconify()
458453
root.wait_visibility() # need main window to be displayed before returning

0 commit comments

Comments
 (0)