Fix Win32 ctypes issues: wintypes aliases, DrawTextW belongs to user32, drop FillRect (use class brush), NULL ptr for EnumDisplayMonitors
Verified on Windows: module imports and enum_monitor_rects() returns correct device-coordinate monitor rects.
This commit is contained in:
1 parent
0e88bf62f5
commit
d6e83565c1
1 file changed
+27
-30
+27
-30
@@ -104,11 +104,18 @@ if sys.platform == "win32":
|
|||||||
TRANSPARENT = 1
|
TRANSPARENT = 1
|
||||||
DEFAULT_GUI_FONT = 17
|
DEFAULT_GUI_FONT = 17
|
||||||
|
|
||||||
WNDPROC = ctypes.WINFUNCTYPE(wt.LRESULT, wt.HWND, wt.UINT, wt.WPARAM, wt.LPARAM)
|
LRESULT = ctypes.c_int64
|
||||||
|
HMONITOR = ctypes.c_void_p
|
||||||
|
HHOOK = ctypes.c_void_p
|
||||||
|
HCURSOR = ctypes.c_void_p
|
||||||
|
ULONG_PTR = ctypes.c_void_p
|
||||||
|
UINT_PTR = ctypes.c_void_p
|
||||||
|
|
||||||
|
WNDPROC = ctypes.WINFUNCTYPE(LRESULT, wt.HWND, wt.UINT, wt.WPARAM, wt.LPARAM)
|
||||||
MONITORENUMPROC = ctypes.WINFUNCTYPE(
|
MONITORENUMPROC = ctypes.WINFUNCTYPE(
|
||||||
wt.BOOL, wt.HMONITOR, wt.HDC, ctypes.POINTER(wt.RECT), wt.LPARAM
|
wt.BOOL, HMONITOR, wt.HDC, ctypes.POINTER(wt.RECT), wt.LPARAM
|
||||||
)
|
)
|
||||||
HOOKPROC = ctypes.WINFUNCTYPE(wt.LRESULT, ctypes.c_int, wt.WPARAM, wt.LPARAM)
|
HOOKPROC = ctypes.WINFUNCTYPE(LRESULT, ctypes.c_int, wt.WPARAM, wt.LPARAM)
|
||||||
|
|
||||||
class WNDCLASSEXW(ctypes.Structure):
|
class WNDCLASSEXW(ctypes.Structure):
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
@@ -119,7 +126,7 @@ if sys.platform == "win32":
|
|||||||
("cbWndExtra", wt.INT),
|
("cbWndExtra", wt.INT),
|
||||||
("hInstance", wt.HINSTANCE),
|
("hInstance", wt.HINSTANCE),
|
||||||
("hIcon", wt.HICON),
|
("hIcon", wt.HICON),
|
||||||
("hCursor", wt.HCURSOR),
|
("hCursor", HCURSOR),
|
||||||
("hbrBackground", wt.HBRUSH),
|
("hbrBackground", wt.HBRUSH),
|
||||||
("lpszMenuName", wt.LPCWSTR),
|
("lpszMenuName", wt.LPCWSTR),
|
||||||
("lpszClassName", wt.LPCWSTR),
|
("lpszClassName", wt.LPCWSTR),
|
||||||
@@ -142,7 +149,7 @@ if sys.platform == "win32":
|
|||||||
("scanCode", wt.DWORD),
|
("scanCode", wt.DWORD),
|
||||||
("flags", wt.DWORD),
|
("flags", wt.DWORD),
|
||||||
("time", wt.DWORD),
|
("time", wt.DWORD),
|
||||||
("dwExtraInfo", wt.ULONG_PTR),
|
("dwExtraInfo", ULONG_PTR),
|
||||||
]
|
]
|
||||||
|
|
||||||
# --- prototypes (64-bit safe) ---
|
# --- prototypes (64-bit safe) ---
|
||||||
@@ -161,9 +168,9 @@ if sys.platform == "win32":
|
|||||||
user32.UpdateWindow.restype = wt.BOOL
|
user32.UpdateWindow.restype = wt.BOOL
|
||||||
user32.SetWindowPos.argtypes = [wt.HWND, wt.HWND, wt.INT, wt.INT, wt.INT, wt.INT, wt.UINT]
|
user32.SetWindowPos.argtypes = [wt.HWND, wt.HWND, wt.INT, wt.INT, wt.INT, wt.INT, wt.UINT]
|
||||||
user32.SetWindowPos.restype = wt.BOOL
|
user32.SetWindowPos.restype = wt.BOOL
|
||||||
user32.SetTimer.argtypes = [wt.HWND, wt.UINT_PTR, wt.UINT, ctypes.c_void_p]
|
user32.SetTimer.argtypes = [wt.HWND, UINT_PTR, wt.UINT, ctypes.c_void_p]
|
||||||
user32.SetTimer.restype = wt.UINT_PTR
|
user32.SetTimer.restype = UINT_PTR
|
||||||
user32.KillTimer.argtypes = [wt.HWND, wt.UINT_PTR]
|
user32.KillTimer.argtypes = [wt.HWND, UINT_PTR]
|
||||||
user32.KillTimer.restype = wt.BOOL
|
user32.KillTimer.restype = wt.BOOL
|
||||||
user32.GetClientRect.argtypes = [wt.HWND, ctypes.POINTER(wt.RECT)]
|
user32.GetClientRect.argtypes = [wt.HWND, ctypes.POINTER(wt.RECT)]
|
||||||
user32.GetClientRect.restype = wt.BOOL
|
user32.GetClientRect.restype = wt.BOOL
|
||||||
@@ -182,24 +189,20 @@ if sys.platform == "win32":
|
|||||||
user32.DispatchMessageW.argtypes = [ctypes.POINTER(wt.MSG)]
|
user32.DispatchMessageW.argtypes = [ctypes.POINTER(wt.MSG)]
|
||||||
user32.DispatchMessageW.restype = wt.LONG
|
user32.DispatchMessageW.restype = wt.LONG
|
||||||
user32.SetWindowsHookExW.argtypes = [wt.INT, HOOKPROC, wt.HINSTANCE, wt.DWORD]
|
user32.SetWindowsHookExW.argtypes = [wt.INT, HOOKPROC, wt.HINSTANCE, wt.DWORD]
|
||||||
user32.SetWindowsHookExW.restype = wt.HHOOK
|
user32.SetWindowsHookExW.restype = HHOOK
|
||||||
user32.CallNextHookEx.argtypes = [wt.HHOOK, ctypes.c_int, wt.WPARAM, wt.LPARAM]
|
user32.CallNextHookEx.argtypes = [HHOOK, ctypes.c_int, wt.WPARAM, wt.LPARAM]
|
||||||
user32.CallNextHookEx.restype = wt.LRESULT
|
user32.CallNextHookEx.restype = LRESULT
|
||||||
user32.UnhookWindowsHookEx.argtypes = [wt.HHOOK]
|
user32.UnhookWindowsHookEx.argtypes = [HHOOK]
|
||||||
user32.UnhookWindowsHookEx.restype = wt.BOOL
|
user32.UnhookWindowsHookEx.restype = wt.BOOL
|
||||||
user32.DestroyWindow.argtypes = [wt.HWND]
|
user32.DestroyWindow.argtypes = [wt.HWND]
|
||||||
user32.DestroyWindow.restype = wt.BOOL
|
user32.DestroyWindow.restype = wt.BOOL
|
||||||
user32.ShowCursor.argtypes = [wt.BOOL]
|
user32.ShowCursor.argtypes = [wt.BOOL]
|
||||||
user32.ShowCursor.restype = wt.INT
|
user32.ShowCursor.restype = wt.INT
|
||||||
user32.DefWindowProcW.argtypes = [wt.HWND, wt.UINT, wt.WPARAM, wt.LPARAM]
|
user32.DefWindowProcW.argtypes = [wt.HWND, wt.UINT, wt.WPARAM, wt.LPARAM]
|
||||||
user32.DefWindowProcW.restype = wt.LRESULT
|
user32.DefWindowProcW.restype = LRESULT
|
||||||
user32.SetProcessDPIAware.argtypes = []
|
user32.SetProcessDPIAware.argtypes = []
|
||||||
user32.SetProcessDPIAware.restype = wt.BOOL
|
user32.SetProcessDPIAware.restype = wt.BOOL
|
||||||
gdi32.CreateSolidBrush.argtypes = [wt.COLORREF]
|
gdi32.CreateSolidBrush.argtypes = [wt.COLORREF]
|
||||||
gdi32.CreateSolidBrush.restype = wt.HBRUSH
|
|
||||||
gdi32.FillRect.argtypes = [wt.HDC, ctypes.POINTER(wt.RECT), wt.HBRUSH]
|
|
||||||
gdi32.FillRect.restype = wt.INT
|
|
||||||
gdi32.DeleteObject.argtypes = [wt.HGDIOBJ]
|
|
||||||
gdi32.DeleteObject.restype = wt.BOOL
|
gdi32.DeleteObject.restype = wt.BOOL
|
||||||
gdi32.SetTextColor.argtypes = [wt.HDC, wt.COLORREF]
|
gdi32.SetTextColor.argtypes = [wt.HDC, wt.COLORREF]
|
||||||
gdi32.SetTextColor.restype = wt.COLORREF
|
gdi32.SetTextColor.restype = wt.COLORREF
|
||||||
@@ -209,8 +212,8 @@ if sys.platform == "win32":
|
|||||||
gdi32.GetStockObject.restype = wt.HGDIOBJ
|
gdi32.GetStockObject.restype = wt.HGDIOBJ
|
||||||
gdi32.SelectObject.argtypes = [wt.HDC, wt.HGDIOBJ]
|
gdi32.SelectObject.argtypes = [wt.HDC, wt.HGDIOBJ]
|
||||||
gdi32.SelectObject.restype = wt.HGDIOBJ
|
gdi32.SelectObject.restype = wt.HGDIOBJ
|
||||||
gdi32.DrawTextW.argtypes = [wt.HDC, wt.LPCWSTR, wt.INT, ctypes.POINTER(wt.RECT), wt.UINT]
|
user32.DrawTextW.argtypes = [wt.HDC, wt.LPCWSTR, wt.INT, ctypes.POINTER(wt.RECT), wt.UINT]
|
||||||
gdi32.DrawTextW.restype = wt.INT
|
user32.DrawTextW.restype = wt.INT
|
||||||
kernel32.GetModuleHandleW.argtypes = [wt.LPCWSTR]
|
kernel32.GetModuleHandleW.argtypes = [wt.LPCWSTR]
|
||||||
kernel32.GetModuleHandleW.restype = wt.HINSTANCE
|
kernel32.GetModuleHandleW.restype = wt.HINSTANCE
|
||||||
kernel32.GetLastError.argtypes = []
|
kernel32.GetLastError.argtypes = []
|
||||||
@@ -229,28 +232,23 @@ if sys.platform == "win32":
|
|||||||
rects.append((r.left, r.top, r.right, r.bottom))
|
rects.append((r.left, r.top, r.right, r.bottom))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
user32.EnumDisplayMonitors(0, 0, MONITORENUMPROC(cb), 0)
|
user32.EnumDisplayMonitors(None, None, MONITORENUMPROC(cb), 0)
|
||||||
return rects
|
return rects
|
||||||
|
|
||||||
def _wndproc(hwnd, msg, wparam, lparam):
|
def _wndproc(hwnd, msg, wparam, lparam):
|
||||||
if msg == WM_ERASEBKGND:
|
global _hint_active
|
||||||
return 1
|
|
||||||
if msg == WM_PAINT:
|
if msg == WM_PAINT:
|
||||||
|
# Background (black) is erased by DefWindowProc via the class brush.
|
||||||
ps = PAINTSTRUCT()
|
ps = PAINTSTRUCT()
|
||||||
hdc = user32.BeginPaint(hwnd, ctypes.byref(ps))
|
hdc = user32.BeginPaint(hwnd, ctypes.byref(ps))
|
||||||
rect = wt.RECT()
|
|
||||||
user32.GetClientRect(hwnd, ctypes.byref(rect))
|
|
||||||
brush = gdi32.CreateSolidBrush(0x000000)
|
|
||||||
gdi32.FillRect(hdc, ctypes.byref(rect), brush)
|
|
||||||
gdi32.DeleteObject(brush)
|
|
||||||
if _hint_active:
|
if _hint_active:
|
||||||
gdi32.SetTextColor(hdc, 0xFFFFFF)
|
gdi32.SetTextColor(hdc, 0xFFFFFF)
|
||||||
gdi32.SetBkMode(hdc, TRANSPARENT)
|
gdi32.SetBkMode(hdc, TRANSPARENT)
|
||||||
font = gdi32.GetStockObject(DEFAULT_GUI_FONT)
|
font = gdi32.GetStockObject(DEFAULT_GUI_FONT)
|
||||||
old = gdi32.SelectObject(hdc, font)
|
old = gdi32.SelectObject(hdc, font)
|
||||||
buf = ctypes.create_unicode_buffer(_hint_text)
|
buf = ctypes.create_unicode_buffer(_hint_text)
|
||||||
gdi32.DrawTextW(
|
user32.DrawTextW(
|
||||||
hdc, buf, -1, ctypes.byref(rect),
|
hdc, buf, -1, ctypes.byref(ps.rcPaint),
|
||||||
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
|
DT_CENTER | DT_VCENTER | DT_SINGLELINE,
|
||||||
)
|
)
|
||||||
if old:
|
if old:
|
||||||
@@ -258,7 +256,6 @@ if sys.platform == "win32":
|
|||||||
user32.EndPaint(hwnd, ctypes.byref(ps))
|
user32.EndPaint(hwnd, ctypes.byref(ps))
|
||||||
return 0
|
return 0
|
||||||
if msg == WM_TIMER:
|
if msg == WM_TIMER:
|
||||||
global _hint_active
|
|
||||||
_hint_active = False
|
_hint_active = False
|
||||||
user32.KillTimer(hwnd, 1)
|
user32.KillTimer(hwnd, 1)
|
||||||
for h in _hwnds:
|
for h in _hwnds:
|
||||||
|
|||||||
Reference in new issue
Block a user