diff --git a/EDMarketConnector.py b/EDMarketConnector.py index cd76ccc07..e48a927c4 100755 --- a/EDMarketConnector.py +++ b/EDMarketConnector.py @@ -253,23 +253,17 @@ def handle_edmc_callback_or_foregrounding() -> None: # noqa: CCR001 logger.trace_if('frontier-auth.windows', 'Begin...') if sys.platform == 'win32': - # If *this* instance hasn't locked, then another already has and we # now need to do the edmc:// checks for auth callback if locked != JournalLockResult.LOCKED: - from ctypes import windll, c_int, create_unicode_buffer, WINFUNCTYPE - from ctypes.wintypes import BOOL, HWND, INT, LPARAM, LPCWSTR, LPWSTR - - EnumWindows = windll.user32.EnumWindows # noqa: N806 - GetClassName = windll.user32.GetClassNameW # noqa: N806 - GetClassName.argtypes = [HWND, LPWSTR, c_int] - GetWindowText = windll.user32.GetWindowTextW # noqa: N806 - GetWindowText.argtypes = [HWND, LPWSTR, c_int] - GetWindowTextLength = windll.user32.GetWindowTextLengthW # noqa: N806 + from ctypes import windll, create_unicode_buffer, WINFUNCTYPE + from ctypes.wintypes import BOOL, HWND, LPARAM + import win32gui + import win32api + GetProcessHandleFromHwnd = windll.oleacc.GetProcessHandleFromHwnd # noqa: N806 SW_RESTORE = 9 # noqa: N806 - SetForegroundWindow = windll.user32.SetForegroundWindow # noqa: N806 ShowWindow = windll.user32.ShowWindow # noqa: N806 ShowWindowAsync = windll.user32.ShowWindowAsync # noqa: N806 @@ -278,14 +272,11 @@ def handle_edmc_callback_or_foregrounding() -> None: # noqa: CCR001 COINIT_DISABLE_OLE1DDE = 0x4 # noqa: N806 CoInitializeEx = windll.ole32.CoInitializeEx # noqa: N806 - ShellExecute = windll.shell32.ShellExecuteW # noqa: N806 - ShellExecute.argtypes = [HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT] - def window_title(h: int) -> str | None: if h: - text_length = GetWindowTextLength(h) + 1 + text_length = win32gui.GetWindowTextLength(h) + 1 buf = create_unicode_buffer(text_length) - if GetWindowText(h, buf, text_length): + if win32gui.GetWindowText(h): return buf.value return None @@ -309,7 +300,7 @@ def enumwindowsproc(window_handle, l_param): # noqa: CCR001 # class name limited to 256 - https://msdn.microsoft.com/en-us/library/windows/desktop/ms633576 cls = create_unicode_buffer(257) # This conditional is exploded to make debugging slightly easier - if GetClassName(window_handle, cls, 257): + if win32gui.GetClassName(window_handle, cls, 257): if cls.value == 'TkTopLevel': if window_title(window_handle) == applongname: if GetProcessHandleFromHwnd(window_handle): @@ -318,11 +309,11 @@ def enumwindowsproc(window_handle, l_param): # noqa: CCR001 CoInitializeEx(0, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE) # Wait for it to be responsive to avoid ShellExecute recursing ShowWindow(window_handle, SW_RESTORE) - ShellExecute(0, None, sys.argv[1], None, None, SW_RESTORE) + win32api.ShellExecute(0, None, sys.argv[1], None, None, SW_RESTORE) else: ShowWindowAsync(window_handle, SW_RESTORE) - SetForegroundWindow(window_handle) + win32gui.SetForegroundWindow(window_handle) return False # Indicate window found, so stop iterating @@ -334,7 +325,7 @@ def enumwindowsproc(window_handle, l_param): # noqa: CCR001 # enumwindwsproc() on each. When an invocation returns False it # stops iterating. # Ref: - EnumWindows(enumwindowsproc, 0) + win32gui.EnumWindows(enumwindowsproc, 0) def already_running_popup(): """Create the "already running" popup.""" @@ -701,13 +692,14 @@ def open_window(systray: 'SysTrayIcon') -> None: if match: if sys.platform == 'win32': # Check that the titlebar will be at least partly on screen - import ctypes - from ctypes.wintypes import POINT + import win32api + import win32con + x = int(match.group(1)) + 16 + y = int(match.group(2)) + 16 + point = (x, y) # https://msdn.microsoft.com/en-us/library/dd145064 - MONITOR_DEFAULTTONULL = 0 # noqa: N806 - if ctypes.windll.user32.MonitorFromPoint(POINT(int(match.group(1)) + 16, int(match.group(2)) + 16), - MONITOR_DEFAULTTONULL): + if win32api.MonitorFromPoint(point, win32con.MONITOR_DEFAULTTONULL): self.w.geometry(config.get_str('geometry')) else: self.w.geometry(config.get_str('geometry')) diff --git a/hotkey/windows.py b/hotkey/windows.py index 671df1e81..51da80be6 100644 --- a/hotkey/windows.py +++ b/hotkey/windows.py @@ -12,6 +12,7 @@ import pywintypes import win32api import win32gui +import win32con from config import config from EDMCLogging import get_main_logger from hotkey import AbstractHotkeyMgr @@ -24,40 +25,10 @@ UnregisterHotKey.argtypes = [HWND, ctypes.c_int] UnregisterHotKey.restype = BOOL -MOD_ALT = 0x0001 -MOD_CONTROL = 0x0002 -MOD_SHIFT = 0x0004 -MOD_WIN = 0x0008 MOD_NOREPEAT = 0x4000 - -WM_QUIT = 0x0012 -WM_HOTKEY = 0x0312 -WM_APP = 0x8000 -WM_SND_GOOD = WM_APP + 1 -WM_SND_BAD = WM_APP + 2 - -VK_BACK = 0x08 -VK_CLEAR = 0x0c -VK_RETURN = 0x0d -VK_SHIFT = 0x10 -VK_CONTROL = 0x11 -VK_MENU = 0x12 -VK_CAPITAL = 0x14 -VK_MODECHANGE = 0x1f -VK_ESCAPE = 0x1b -VK_SPACE = 0x20 -VK_DELETE = 0x2e -VK_LWIN = 0x5b -VK_RWIN = 0x5c -VK_NUMPAD0 = 0x60 -VK_DIVIDE = 0x6f -VK_F1 = 0x70 -VK_F24 = 0x87 +WM_SND_GOOD = win32con.WM_APP + 1 +WM_SND_BAD = win32con.WM_APP + 2 VK_OEM_MINUS = 0xbd -VK_NUMLOCK = 0x90 -VK_SCROLL = 0x91 -VK_PROCESSKEY = 0xe5 -VK_OEM_CLEAR = 0xfe # VirtualKey mapping values # @@ -200,7 +171,7 @@ def unregister(self) -> None: logger.debug('Thread is/was running') self.thread = None # type: ignore logger.debug('Telling thread WM_QUIT') - win32gui.PostThreadMessage(thread.ident, WM_QUIT, 0, 0) + win32gui.PostThreadMessage(thread.ident, win32con.WM_QUIT, 0, 0) logger.debug('Joining thread') thread.join() # Wait for it to unregister hotkey and quit @@ -226,7 +197,7 @@ def worker(self, keycode, modifiers) -> None: # noqa: CCR001 logger.debug('Entering GetMessage() loop...') while win32gui.GetMessage(ctypes.byref(msg), None, 0, 0) != 0: logger.debug('Got message') - if msg.message == WM_HOTKEY: + if msg.message == win32con.WM_HOTKEY: logger.debug('WM_HOTKEY') if ( @@ -284,31 +255,32 @@ def fromevent(self, event) -> bool | tuple | None: # noqa: CCR001 :param event: tk event ? :return: False to retain previous, None to not use, else (keycode, modifiers) """ - modifiers = ((win32api.GetKeyState(VK_MENU) & 0x8000) and MOD_ALT) \ - | ((win32api.GetKeyState(VK_CONTROL) & 0x8000) and MOD_CONTROL) \ - | ((win32api.GetKeyState(VK_SHIFT) & 0x8000) and MOD_SHIFT) \ - | ((win32api.GetKeyState(VK_LWIN) & 0x8000) and MOD_WIN) \ - | ((win32api.GetKeyState(VK_RWIN) & 0x8000) and MOD_WIN) + modifiers = ((win32api.GetKeyState(win32con.VK_MENU) & 0x8000) and win32con.MOD_ALT) \ + | ((win32api.GetKeyState(win32con.VK_CONTROL) & 0x8000) and win32con.MOD_CONTROL) \ + | ((win32api.GetKeyState(win32con.VK_SHIFT) & 0x8000) and win32con.MOD_SHIFT) \ + | ((win32api.GetKeyState(win32con.VK_LWIN) & 0x8000) and win32con.MOD_WIN) \ + | ((win32api.GetKeyState(win32con.VK_RWIN) & 0x8000) and win32con.MOD_WIN) keycode = event.keycode - if keycode in (VK_SHIFT, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN): + if keycode in (win32con.VK_SHIFT, win32con.VK_CONTROL, win32con.VK_MENU, win32con.VK_LWIN, win32con.VK_RWIN): return 0, modifiers if not modifiers: - if keycode == VK_ESCAPE: # Esc = retain previous + if keycode == win32con.VK_ESCAPE: # Esc = retain previous return False - if keycode in (VK_BACK, VK_DELETE, VK_CLEAR, VK_OEM_CLEAR): # BkSp, Del, Clear = clear hotkey + if keycode in (win32con.VK_BACK, win32con.VK_DELETE, + win32con.VK_CLEAR, win32con.VK_OEM_CLEAR): # BkSp, Del, Clear = clear hotkey return None if ( - keycode in (VK_RETURN, VK_SPACE, VK_OEM_MINUS) or ord('A') <= keycode <= ord('Z') + keycode in (win32con.VK_RETURN, win32con.VK_SPACE, VK_OEM_MINUS) or ord('A') <= keycode <= ord('Z') ): # don't allow keys needed for typing in System Map winsound.MessageBeep() return None - if (keycode in (VK_NUMLOCK, VK_SCROLL, VK_PROCESSKEY) - or VK_CAPITAL <= keycode <= VK_MODECHANGE): # ignore unmodified mode switch keys + if (keycode in (win32con.VK_NUMLOCK, win32con.VK_SCROLL, win32con.VK_PROCESSKEY) + or win32con.VK_CAPITAL <= keycode <= win32con.VK_MODECHANGE): # ignore unmodified mode switch keys return 0, modifiers # See if the keycode is usable and available @@ -329,26 +301,26 @@ def display(self, keycode, modifiers) -> str: :return: string form """ text = '' - if modifiers & MOD_WIN: + if modifiers & win32con.MOD_WIN: text += '❖+' - if modifiers & MOD_CONTROL: + if modifiers & win32con.MOD_CONTROL: text += 'Ctrl+' - if modifiers & MOD_ALT: + if modifiers & win32con.MOD_ALT: text += 'Alt+' - if modifiers & MOD_SHIFT: + if modifiers & win32con.MOD_SHIFT: text += '⇧+' - if VK_NUMPAD0 <= keycode <= VK_DIVIDE: + if win32con.VK_NUMPAD0 <= keycode <= win32con.VK_DIVIDE: text += '№' if not keycode: pass - elif VK_F1 <= keycode <= VK_F24: - text += f'F{keycode + 1 - VK_F1}' + elif win32con.VK_F1 <= keycode <= win32con.VK_F24: + text += f'F{keycode + 1 - win32con.VK_F1}' elif keycode in WindowsHotkeyMgr.DISPLAY: # specials text += WindowsHotkeyMgr.DISPLAY[keycode] diff --git a/monitor.py b/monitor.py index 5a971c694..2f508bf9d 100644 --- a/monitor.py +++ b/monitor.py @@ -2127,7 +2127,7 @@ def WindowTitle(h): # noqa: N802 if h: length = win32gui.GetWindowTextLength(h) + 1 buf = ctypes.create_unicode_buffer(length) - if win32gui.GetWindowText(h, buf, length): + if win32gui.GetWindowText(h): return buf.value return None