mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-12 15:27:14 +03:00
[#1805] pywin32 Handoff
This commit is contained in:
parent
b10548da57
commit
17a7af959a
@ -7,41 +7,23 @@ See LICENSE file.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import ctypes
|
||||
import functools
|
||||
import pathlib
|
||||
import sys
|
||||
import uuid
|
||||
import winreg
|
||||
from ctypes.wintypes import DWORD, HANDLE
|
||||
from typing import Literal
|
||||
from config import AbstractConfig, applongname, appname, logger
|
||||
from win32comext.shell import shell
|
||||
|
||||
assert sys.platform == 'win32'
|
||||
|
||||
REG_RESERVED_ALWAYS_ZERO = 0
|
||||
|
||||
# This is the only way to do this from python without external deps (which do this anyway).
|
||||
FOLDERID_Documents = uuid.UUID('{FDD39AD0-238F-46AF-ADB4-6C85480369C7}')
|
||||
FOLDERID_LocalAppData = uuid.UUID('{F1B32785-6FBA-4FCF-9D55-7B8E7F157091}')
|
||||
FOLDERID_Profile = uuid.UUID('{5E6C858F-0E22-4760-9AFE-EA3317B67173}')
|
||||
FOLDERID_SavedGames = uuid.UUID('{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}')
|
||||
|
||||
SHGetKnownFolderPath = ctypes.windll.shell32.SHGetKnownFolderPath
|
||||
SHGetKnownFolderPath.argtypes = [ctypes.c_char_p, DWORD, HANDLE, ctypes.POINTER(ctypes.c_wchar_p)]
|
||||
|
||||
CoTaskMemFree = ctypes.windll.ole32.CoTaskMemFree
|
||||
CoTaskMemFree.argtypes = [ctypes.c_void_p]
|
||||
|
||||
|
||||
def known_folder_path(guid: uuid.UUID) -> str | None:
|
||||
"""Look up a Windows GUID to actual folder path name."""
|
||||
buf = ctypes.c_wchar_p()
|
||||
if SHGetKnownFolderPath(ctypes.create_string_buffer(guid.bytes_le), 0, 0, ctypes.byref(buf)):
|
||||
return None
|
||||
retval = buf.value # copy data
|
||||
CoTaskMemFree(buf) # and free original
|
||||
return retval
|
||||
return shell.SHGetKnownFolderPath(guid, 0, 0)
|
||||
|
||||
|
||||
class WinConfig(AbstractConfig):
|
||||
@ -49,7 +31,8 @@ class WinConfig(AbstractConfig):
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.app_dir_path = pathlib.Path(known_folder_path(FOLDERID_LocalAppData)) / appname # type: ignore
|
||||
if local_appdata := known_folder_path(shell.FOLDERID_LocalAppData):
|
||||
self.app_dir_path = pathlib.Path(local_appdata) / appname
|
||||
self.app_dir_path.mkdir(exist_ok=True)
|
||||
|
||||
self.plugin_dir_path = self.app_dir_path / 'plugins'
|
||||
@ -65,7 +48,7 @@ class WinConfig(AbstractConfig):
|
||||
self.home_path = pathlib.Path.home()
|
||||
|
||||
journal_dir_path = pathlib.Path(
|
||||
known_folder_path(FOLDERID_SavedGames)) / 'Frontier Developments' / 'Elite Dangerous' # type: ignore
|
||||
known_folder_path(shell.FOLDERID_SavedGames)) / 'Frontier Developments' / 'Elite Dangerous' # type: ignore
|
||||
self.default_journal_dir_path = journal_dir_path if journal_dir_path.is_dir() else None # type: ignore
|
||||
|
||||
REGISTRY_SUBKEY = r'Software\Marginal\EDMarketConnector' # noqa: N806
|
||||
@ -84,7 +67,7 @@ class WinConfig(AbstractConfig):
|
||||
|
||||
self.identifier = applongname
|
||||
if (outdir_str := self.get_str('outdir')) is None or not pathlib.Path(outdir_str).is_dir():
|
||||
docs = known_folder_path(FOLDERID_Documents)
|
||||
docs = known_folder_path(shell.FOLDERID_Documents)
|
||||
self.set("outdir", docs if docs is not None else self.home)
|
||||
|
||||
def __get_regentry(self, key: str) -> None | list | str | int:
|
||||
|
@ -8,7 +8,10 @@ import sys
|
||||
import threading
|
||||
import tkinter as tk
|
||||
import winsound
|
||||
from ctypes.wintypes import DWORD, HWND, LONG, LPWSTR, MSG, ULONG, WORD
|
||||
from ctypes.wintypes import DWORD, LONG, MSG, ULONG, WORD
|
||||
import pywintypes
|
||||
import win32api
|
||||
import win32gui
|
||||
from config import config
|
||||
from EDMCLogging import get_main_logger
|
||||
from hotkey import AbstractHotkeyMgr
|
||||
@ -17,26 +20,20 @@ assert sys.platform == 'win32'
|
||||
|
||||
logger = get_main_logger()
|
||||
|
||||
RegisterHotKey = ctypes.windll.user32.RegisterHotKey
|
||||
UnregisterHotKey = ctypes.windll.user32.UnregisterHotKey
|
||||
UnregisterHotKey = ctypes.windll.user32.UnregisterHotKey # TODO: Coming Soon
|
||||
|
||||
MOD_ALT = 0x0001
|
||||
MOD_CONTROL = 0x0002
|
||||
MOD_SHIFT = 0x0004
|
||||
MOD_WIN = 0x0008
|
||||
MOD_NOREPEAT = 0x4000
|
||||
|
||||
GetMessage = ctypes.windll.user32.GetMessageW
|
||||
TranslateMessage = ctypes.windll.user32.TranslateMessage
|
||||
DispatchMessage = ctypes.windll.user32.DispatchMessageW
|
||||
PostThreadMessage = ctypes.windll.user32.PostThreadMessageW
|
||||
WM_QUIT = 0x0012
|
||||
WM_HOTKEY = 0x0312
|
||||
WM_APP = 0x8000
|
||||
WM_SND_GOOD = WM_APP + 1
|
||||
WM_SND_BAD = WM_APP + 2
|
||||
|
||||
GetKeyState = ctypes.windll.user32.GetKeyState
|
||||
MapVirtualKey = ctypes.windll.user32.MapVirtualKeyW
|
||||
VK_BACK = 0x08
|
||||
VK_CLEAR = 0x0c
|
||||
VK_RETURN = 0x0d
|
||||
@ -60,10 +57,13 @@ VK_SCROLL = 0x91
|
||||
VK_PROCESSKEY = 0xe5
|
||||
VK_OEM_CLEAR = 0xfe
|
||||
|
||||
GetForegroundWindow = ctypes.windll.user32.GetForegroundWindow
|
||||
GetWindowText = ctypes.windll.user32.GetWindowTextW
|
||||
GetWindowText.argtypes = [HWND, LPWSTR, ctypes.c_int]
|
||||
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
|
||||
# VirtualKey mapping values
|
||||
# <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeyexa>
|
||||
MAPVK_VK_TO_VSC = 0
|
||||
MAPVK_VSC_TO_VK = 1
|
||||
MAPVK_VK_TO_CHAR = 2
|
||||
MAPVK_VSC_TO_VK_EX = 3
|
||||
MAPVK_VK_TO_VSC_EX = 4
|
||||
|
||||
|
||||
def window_title(h) -> str:
|
||||
@ -74,9 +74,9 @@ def window_title(h) -> str:
|
||||
:return: Window title.
|
||||
"""
|
||||
if h:
|
||||
title_length = GetWindowTextLength(h) + 1
|
||||
title_length = win32gui.GetWindowTextLength(h) + 1
|
||||
buf = ctypes.create_unicode_buffer(title_length)
|
||||
if GetWindowText(h, buf, title_length):
|
||||
if win32gui.GetWindowText(h, buf, title_length):
|
||||
return buf.value
|
||||
|
||||
return ''
|
||||
@ -197,7 +197,7 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
logger.debug('Thread is/was running')
|
||||
self.thread = None # type: ignore
|
||||
logger.debug('Telling thread WM_QUIT')
|
||||
PostThreadMessage(thread.ident, WM_QUIT, 0, 0)
|
||||
win32gui.PostThreadMessage(thread.ident, WM_QUIT, 0, 0)
|
||||
logger.debug('Joining thread')
|
||||
thread.join() # Wait for it to unregister hotkey and quit
|
||||
|
||||
@ -210,8 +210,10 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
"""Handle hotkeys."""
|
||||
logger.debug('Begin...')
|
||||
# Hotkey must be registered by the thread that handles it
|
||||
if not RegisterHotKey(None, 1, modifiers | MOD_NOREPEAT, keycode):
|
||||
logger.debug("We're not the right thread?")
|
||||
try:
|
||||
win32gui.RegisterHotKey(None, 1, modifiers | MOD_NOREPEAT, keycode)
|
||||
except pywintypes.error:
|
||||
logger.exception("We're not the right thread?")
|
||||
self.thread = None # type: ignore
|
||||
return
|
||||
|
||||
@ -219,14 +221,14 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
|
||||
msg = MSG()
|
||||
logger.debug('Entering GetMessage() loop...')
|
||||
while GetMessage(ctypes.byref(msg), None, 0, 0) != 0:
|
||||
while win32gui.GetMessage(ctypes.byref(msg), None, 0, 0) != 0:
|
||||
logger.debug('Got message')
|
||||
if msg.message == WM_HOTKEY:
|
||||
logger.debug('WM_HOTKEY')
|
||||
|
||||
if (
|
||||
config.get_int('hotkey_always')
|
||||
or window_title(GetForegroundWindow()).startswith('Elite - Dangerous')
|
||||
config.get_int('hotkey_always')
|
||||
or window_title(win32gui.GetForegroundWindow()).startswith('Elite - Dangerous')
|
||||
):
|
||||
if not config.shutting_down:
|
||||
logger.debug('Sending event <<Invoke>>')
|
||||
@ -236,8 +238,10 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
logger.debug('Passing key on')
|
||||
UnregisterHotKey(None, 1)
|
||||
SendInput(1, fake, ctypes.sizeof(INPUT))
|
||||
if not RegisterHotKey(None, 1, modifiers | MOD_NOREPEAT, keycode):
|
||||
logger.debug("We aren't registered for this ?")
|
||||
try:
|
||||
win32gui.RegisterHotKey(None, 1, modifiers | MOD_NOREPEAT, keycode)
|
||||
except pywintypes.error:
|
||||
logger.exception("We aren't registered for this ?")
|
||||
break
|
||||
|
||||
elif msg.message == WM_SND_GOOD:
|
||||
@ -250,8 +254,8 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
|
||||
else:
|
||||
logger.debug('Something else')
|
||||
TranslateMessage(ctypes.byref(msg))
|
||||
DispatchMessage(ctypes.byref(msg))
|
||||
win32gui.TranslateMessage(ctypes.byref(msg))
|
||||
win32gui.DispatchMessage(ctypes.byref(msg))
|
||||
|
||||
logger.debug('Exited GetMessage() loop.')
|
||||
UnregisterHotKey(None, 1)
|
||||
@ -266,7 +270,7 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
"""Stop acquiring hotkey state."""
|
||||
pass
|
||||
|
||||
def fromevent(self, event) -> bool | tuple | None: # noqa: CCR001
|
||||
def fromevent(self, event) -> bool | tuple | None:
|
||||
"""
|
||||
Return configuration (keycode, modifiers) or None=clear or False=retain previous.
|
||||
|
||||
@ -277,11 +281,11 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
:param event: tk event ?
|
||||
:return: False to retain previous, None to not use, else (keycode, modifiers)
|
||||
"""
|
||||
modifiers = ((GetKeyState(VK_MENU) & 0x8000) and MOD_ALT) \
|
||||
| ((GetKeyState(VK_CONTROL) & 0x8000) and MOD_CONTROL) \
|
||||
| ((GetKeyState(VK_SHIFT) & 0x8000) and MOD_SHIFT) \
|
||||
| ((GetKeyState(VK_LWIN) & 0x8000) and MOD_WIN) \
|
||||
| ((GetKeyState(VK_RWIN) & 0x8000) and MOD_WIN)
|
||||
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)
|
||||
keycode = event.keycode
|
||||
|
||||
if keycode in (VK_SHIFT, VK_CONTROL, VK_MENU, VK_LWIN, VK_RWIN):
|
||||
@ -295,7 +299,7 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
return None
|
||||
|
||||
if (
|
||||
keycode in (VK_RETURN, VK_SPACE, VK_OEM_MINUS) or ord('A') <= keycode <= ord('Z')
|
||||
keycode in (VK_RETURN, 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
|
||||
@ -305,12 +309,13 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
return 0, modifiers
|
||||
|
||||
# See if the keycode is usable and available
|
||||
if RegisterHotKey(None, 2, modifiers | MOD_NOREPEAT, keycode):
|
||||
try:
|
||||
win32gui.RegisterHotKey(None, 2, modifiers | MOD_NOREPEAT, keycode)
|
||||
UnregisterHotKey(None, 2)
|
||||
return keycode, modifiers
|
||||
|
||||
winsound.MessageBeep()
|
||||
return None
|
||||
except pywintypes.error:
|
||||
winsound.MessageBeep()
|
||||
return None
|
||||
|
||||
def display(self, keycode, modifiers) -> str:
|
||||
"""
|
||||
@ -346,7 +351,7 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
text += WindowsHotkeyMgr.DISPLAY[keycode]
|
||||
|
||||
else:
|
||||
c = MapVirtualKey(keycode, 2) # printable ?
|
||||
c = win32api.MapVirtualKey(keycode, MAPVK_VK_TO_CHAR)
|
||||
if not c: # oops not printable
|
||||
text += '⁈'
|
||||
|
||||
@ -361,9 +366,9 @@ class WindowsHotkeyMgr(AbstractHotkeyMgr):
|
||||
def play_good(self) -> None:
|
||||
"""Play the 'good' sound."""
|
||||
if self.thread:
|
||||
PostThreadMessage(self.thread.ident, WM_SND_GOOD, 0, 0)
|
||||
win32gui.PostThreadMessage(self.thread.ident, WM_SND_GOOD, 0, 0)
|
||||
|
||||
def play_bad(self) -> None:
|
||||
"""Play the 'bad' sound."""
|
||||
if self.thread:
|
||||
PostThreadMessage(self.thread.ident, WM_SND_BAD, 0, 0)
|
||||
win32gui.PostThreadMessage(self.thread.ident, WM_SND_BAD, 0, 0)
|
||||
|
18
monitor.py
18
monitor.py
@ -36,23 +36,15 @@ MAX_FCMATERIALS_DISCREPANCY = 5 # Timestamp difference in seconds
|
||||
|
||||
if sys.platform == 'win32':
|
||||
import ctypes
|
||||
from ctypes.wintypes import BOOL, HWND, LPARAM, LPWSTR
|
||||
from ctypes.wintypes import BOOL, HWND, LPARAM
|
||||
import win32gui
|
||||
|
||||
from watchdog.events import FileSystemEventHandler, FileSystemEvent
|
||||
from watchdog.observers import Observer
|
||||
from watchdog.observers.api import BaseObserver
|
||||
|
||||
EnumWindows = ctypes.windll.user32.EnumWindows
|
||||
EnumWindowsProc = ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM)
|
||||
|
||||
CloseHandle = ctypes.windll.kernel32.CloseHandle
|
||||
|
||||
GetWindowText = ctypes.windll.user32.GetWindowTextW
|
||||
GetWindowText.argtypes = [HWND, LPWSTR, ctypes.c_int]
|
||||
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
|
||||
GetWindowTextLength.argtypes = [ctypes.wintypes.HWND]
|
||||
GetWindowTextLength.restype = ctypes.c_int
|
||||
|
||||
GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd
|
||||
|
||||
else:
|
||||
@ -2131,9 +2123,9 @@ class EDLogs(FileSystemEventHandler):
|
||||
if sys.platform == 'win32':
|
||||
def WindowTitle(h): # noqa: N802
|
||||
if h:
|
||||
length = GetWindowTextLength(h) + 1
|
||||
length = win32gui.GetWindowTextLength(h) + 1
|
||||
buf = ctypes.create_unicode_buffer(length)
|
||||
if GetWindowText(h, buf, length):
|
||||
if win32gui.GetWindowText(h, buf, length):
|
||||
return buf.value
|
||||
return None
|
||||
|
||||
@ -2147,7 +2139,7 @@ class EDLogs(FileSystemEventHandler):
|
||||
|
||||
return True
|
||||
|
||||
return not EnumWindows(EnumWindowsProc(callback), 0)
|
||||
return not win32gui.EnumWindows(EnumWindowsProc(callback), 0)
|
||||
|
||||
return False
|
||||
|
||||
|
10
prefs.py
10
prefs.py
@ -188,7 +188,8 @@ class AutoInc(contextlib.AbstractContextManager):
|
||||
if sys.platform == 'win32':
|
||||
import ctypes
|
||||
import winreg
|
||||
from ctypes.wintypes import HINSTANCE, HWND, LPCWSTR, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT
|
||||
from ctypes.wintypes import HINSTANCE, LPCWSTR, LPWSTR, MAX_PATH, POINT, RECT, SIZE, UINT
|
||||
import win32gui
|
||||
is_wine = False
|
||||
try:
|
||||
WINE_REGISTRY_KEY = r'HKEY_LOCAL_MACHINE\Software\Wine'
|
||||
@ -219,11 +220,6 @@ if sys.platform == 'win32':
|
||||
ctypes.POINTER(RECT)
|
||||
]
|
||||
|
||||
GetParent = ctypes.windll.user32.GetParent
|
||||
GetParent.argtypes = [HWND]
|
||||
GetWindowRect = ctypes.windll.user32.GetWindowRect
|
||||
GetWindowRect.argtypes = [HWND, ctypes.POINTER(RECT)]
|
||||
|
||||
SHGetLocalizedName = ctypes.windll.shell32.SHGetLocalizedName
|
||||
SHGetLocalizedName.argtypes = [LPCWSTR, LPWSTR, UINT, ctypes.POINTER(ctypes.c_int)]
|
||||
|
||||
@ -314,7 +310,7 @@ class PreferencesDialog(tk.Toplevel):
|
||||
# Ensure fully on-screen
|
||||
if sys.platform == 'win32' and CalculatePopupWindowPosition:
|
||||
position = RECT()
|
||||
GetWindowRect(GetParent(self.winfo_id()), position)
|
||||
win32gui.GetWindowRect(win32gui.GetParent(self.winfo_id()), position)
|
||||
if CalculatePopupWindowPosition(
|
||||
POINT(parent.winfo_rootx(), parent.winfo_rooty()),
|
||||
SIZE(position.right - position.left, position.bottom - position.top), # type: ignore
|
||||
|
@ -42,8 +42,6 @@ pytest==8.2.0
|
||||
pytest-cov==5.0.0 # Pytest code coverage support
|
||||
coverage[toml]==7.5.0 # pytest-cov dep. This is here to ensure that it includes TOML support for pyproject.toml configs
|
||||
coverage-conditional-plugin==0.9.0
|
||||
# For manipulating folder permissions and the like.
|
||||
pywin32==306; sys_platform == 'win32'
|
||||
|
||||
|
||||
# All of the normal requirements
|
||||
|
@ -3,3 +3,5 @@ pillow==10.3.0
|
||||
watchdog==4.0.0
|
||||
simplesystray==0.1.0; sys_platform == 'win32'
|
||||
semantic-version==2.10.0
|
||||
# For manipulating folder permissions and the like.
|
||||
pywin32==306; sys_platform == 'win32'
|
9
stats.py
9
stats.py
@ -25,17 +25,14 @@ logger = EDMCLogging.get_main_logger()
|
||||
|
||||
if sys.platform == 'win32':
|
||||
import ctypes
|
||||
from ctypes.wintypes import HWND, POINT, RECT, SIZE, UINT
|
||||
from ctypes.wintypes import POINT, RECT, SIZE, UINT
|
||||
import win32gui
|
||||
|
||||
try:
|
||||
CalculatePopupWindowPosition = ctypes.windll.user32.CalculatePopupWindowPosition
|
||||
CalculatePopupWindowPosition.argtypes = [
|
||||
ctypes.POINTER(POINT), ctypes.POINTER(SIZE), UINT, ctypes.POINTER(RECT), ctypes.POINTER(RECT)
|
||||
]
|
||||
GetParent = ctypes.windll.user32.GetParent
|
||||
GetParent.argtypes = [HWND]
|
||||
GetWindowRect = ctypes.windll.user32.GetWindowRect
|
||||
GetWindowRect.argtypes = [HWND, ctypes.POINTER(RECT)]
|
||||
|
||||
except Exception: # Not supported under Wine 4.0
|
||||
CalculatePopupWindowPosition = None # type: ignore
|
||||
@ -423,7 +420,7 @@ class StatsResults(tk.Toplevel):
|
||||
# Ensure fully on-screen
|
||||
if sys.platform == 'win32' and CalculatePopupWindowPosition:
|
||||
position = RECT()
|
||||
GetWindowRect(GetParent(self.winfo_id()), position)
|
||||
win32gui.GetWindowRect(win32gui.GetParent(self.winfo_id()), position)
|
||||
if CalculatePopupWindowPosition(
|
||||
POINT(parent.winfo_rootx(), parent.winfo_rooty()),
|
||||
# - is evidently supported on the C side
|
||||
|
11
theme.py
11
theme.py
@ -34,6 +34,7 @@ if sys.platform == "linux":
|
||||
if sys.platform == 'win32':
|
||||
import ctypes
|
||||
from ctypes.wintypes import DWORD, LPCVOID, LPCWSTR
|
||||
import win32gui
|
||||
AddFontResourceEx = ctypes.windll.gdi32.AddFontResourceExW
|
||||
AddFontResourceEx.restypes = [LPCWSTR, DWORD, LPCVOID] # type: ignore
|
||||
FR_PRIVATE = 0x10
|
||||
@ -427,8 +428,6 @@ class _Theme:
|
||||
GWL_EXSTYLE = -20 # noqa: N806 # ctypes
|
||||
WS_EX_APPWINDOW = 0x00040000 # noqa: N806 # ctypes
|
||||
WS_EX_LAYERED = 0x00080000 # noqa: N806 # ctypes
|
||||
GetWindowLongW = ctypes.windll.user32.GetWindowLongW # noqa: N806 # ctypes
|
||||
SetWindowLongW = ctypes.windll.user32.SetWindowLongW # noqa: N806 # ctypes
|
||||
|
||||
# FIXME: Lose the "treat this like a boolean" bullshit
|
||||
if theme == self.THEME_DEFAULT:
|
||||
@ -445,14 +444,14 @@ class _Theme:
|
||||
|
||||
root.withdraw()
|
||||
root.update_idletasks() # Size and windows styles get recalculated here
|
||||
hwnd = ctypes.windll.user32.GetParent(root.winfo_id())
|
||||
SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) & ~WS_MAXIMIZEBOX) # disable maximize
|
||||
hwnd = win32gui.GetParent(root.winfo_id())
|
||||
win32gui.SetWindowLong(hwnd, GWL_STYLE, win32gui.GetWindowLong(hwnd, GWL_STYLE) & ~WS_MAXIMIZEBOX) # disable maximize
|
||||
|
||||
if theme == self.THEME_TRANSPARENT:
|
||||
SetWindowLongW(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_LAYERED) # Add to taskbar
|
||||
win32gui.SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_LAYERED) # Add to taskbar
|
||||
|
||||
else:
|
||||
SetWindowLongW(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW) # Add to taskbar
|
||||
win32gui.SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW) # Add to taskbar
|
||||
|
||||
root.deiconify()
|
||||
root.wait_visibility() # need main window to be displayed before returning
|
||||
|
Loading…
x
Reference in New Issue
Block a user