1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-22 11:50:28 +03:00

monitor: Just use the pywin32 win32gui.GetWindowText(), it works

After over an hour's struggle trying to get the win32/user32
`GetWindowTextW()` prototyped properly, and running into problem after problem:

    1. Once you properly prototype this, including defining the 2nd `lpString`
      parameter as 'out', ctypes wants to just *return* that.
    2. This leads to then implementing a `.errcheck` property so that you
      can *also* check the INT result for errors.
    3. But then you just run into another error.

I finally found <https://stackoverflow.com/a/10905155> which pointed out
you can simply use `win32gui.GetWindowText()` from `pywin32`.  Tested, it
simply works, no errors/exceptions.
This commit is contained in:
Athanasius 2023-01-12 17:35:01 +00:00
parent d5a1fc4001
commit 2c469441e0
No known key found for this signature in database
GPG Key ID: 772697E181BB2767
3 changed files with 7 additions and 25 deletions

View File

@ -50,8 +50,9 @@ if sys.platform == 'darwin':
elif sys.platform == 'win32':
import ctypes
from ctypes import WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HANDLE, HWND, LPARAM, LPWSTR
from ctypes.wintypes import BOOL, HANDLE, HWND, LPARAM
import win32gui
from watchdog.events import FileCreatedEvent, FileSystemEventHandler
from watchdog.observers import Observer
@ -73,24 +74,6 @@ elif sys.platform == 'win32':
paramflags_closehandle = (1, "hObject"),
CloseHandle = prototype(("CloseHandle", windll.kernel32), paramflags_closehandle)
# <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextw>
# int GetWindowTextW(
# [in] HWND hWnd,
# [out] LPWSTR lpString,
# [in] int nMaxCount
# );
prototype = WINFUNCTYPE(ctypes.c_int, HWND, LPWSTR, ctypes.c_int)
paramflags_getwindowtextw = (1, "hWnd"), (2, "lpString"), (1, "nMaxCount")
GetWindowTextW = prototype(("GetWindowTextW", windll.user32), paramflags_getwindowtextw)
# <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowtextlengthw>
# int GetWindowTextLengthW(
# [in] HWND hWnd
# );
prototype = WINFUNCTYPE(ctypes.c_int, HWND)
paramflags_getwindowtextlengthw = (1, "hWnd"),
GetWindowTextLengthW = prototype(("GetWindowTextLengthW", windll.user32), paramflags_getwindowtextw)
GetProcessHandleFromHwnd = ctypes.windll.oleacc.GetProcessHandleFromHwnd
else:
@ -2060,10 +2043,8 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
elif sys.platform == 'win32':
def WindowTitle(h): # noqa: N802 # type: ignore
if h:
length = GetWindowTextLengthW(h) + 1
buf = ctypes.create_unicode_buffer(length)
if GetWindowTextW(h, buf, length):
return buf.value
return win32gui.GetWindowText(h)
return None
def callback(hWnd, lParam): # noqa: N803

View File

@ -48,8 +48,6 @@ pytest==7.2.0
pytest-cov==4.0.0 # Pytest code coverage support
coverage[toml]==7.0.5 # pytest-cov dep. This is here to ensure that it includes TOML support for pyproject.toml configs
coverage-conditional-plugin==0.8.0
# For manipulating folder permissions and the like.
pywin32==305; sys_platform == 'win32'
# All of the normal requirements

View File

@ -7,5 +7,8 @@ infi.systray==0.1.12; sys_platform == 'win32'
# pyyaml==5.3.1 watchdog dep
semantic-version==2.10.0
# Used both by some tests *and* now in monitor.py
pywin32==305; sys_platform == 'win32'
# Base requirement for MacOS
pyobjc; sys_platform == 'darwin'