GetGUIThreadInfo () с pywin32 - PullRequest
       50

GetGUIThreadInfo () с pywin32

2 голосов
/ 23 января 2020

Я пытаюсь следовать этому ответу , и я достиг точки, где a должен позвонить

GetGUIThreadInfo()

, но я не могу найти это в pywin32 документации я использую.

То, что я до сих пор делал, это

import win32api
import win32gui
import win32process

test1 = win32gui.FindWindowEx(0, 0, 0, "notepad")
(test1tid, test1pid) = win32process.GetWindowThreadProcessId(test1)
test1hwndFocus = win32process.GetGUIThreadInfo(test1tid)

, но последняя строка полностью составлена, так как я не могу найти правильный способ вызова функции.

Update1:

Думаю, я добился определенного прогресса, но теперь моя структура просто возвращает 0, когда я ожидаю некоторого hwnd ... так что, возможно, моя структура не записана, я думаю, что это может быть из-за типов в моем структура, но как мне найти нужные типы?

import win32api
import win32gui
import win32process
import ctypes

class RECT(ctypes.Structure):
    _fields_ = [
    ("left", ctypes.c_ulong),
    ("top", ctypes.c_ulong),
    ("right", ctypes.c_ulong),
    ("bottom", ctypes.c_ulong)
    ]


class GUITHREADINFO(ctypes.Structure):
    _fields_ = [
    ("cbSize", ctypes.c_ulong),
    ("flags", ctypes.c_ulong),
    ("hwndActive", ctypes.c_ulong),
    ("hwndFocus", ctypes.c_ulong),
    ("hwndCapture", ctypes.c_ulong),
    ("hwndMenuOwner", ctypes.c_ulong),
    ("hwndMoveSize", ctypes.c_ulong),
    ("hwndCaret", ctypes.c_ulong),
    ("rcCaret", RECT)
    ]

guiThreadInfoStruct = GUITHREADINFO()


ctypes.sizeof(gtitest)

test1 = win32gui.FindWindowEx(0, 0, 0, "notepad")
(test1tid, test1pid) = win32process.GetWindowThreadProcessId(test1)
ctypes.windll.user32.GetGUIThreadInfo(test1tid, guiThreadInfoStruct)
print (guiThreadInfoStruct.hwndFocus)

Update2:

Я нашел типы здесь

update3:

Если кто-нибудь захочет посмотреть, что я использовал для go, посмотрите здесь

1 Ответ

1 голос
/ 24 января 2020

Очевидно, [MS.Docs]: функция GetGUIThreadInfo не упакована в PyWin32 , поэтому необходимо использовать альтернативные способы. Один из них вызывает его через [Python 3.Docs]: ctypes - библиотека сторонних функций для Python (включает в себя написание большого количества дополнительного кода).

code00.py :

#!/usr/bin/env python

import sys
import win32gui as wgui
import win32process as wproc
import win32con as wcon

import ctypes as ct
from ctypes import wintypes as wt


class GUITHREADINFO(ct.Structure):
    _fields_ = [
        ("cbSize", wt.DWORD),
        ("flags", wt.DWORD),
        ("hwndActive", wt.HWND),
        ("hwndFocus", wt.HWND),
        ("hwndCapture", wt.HWND),
        ("hwndMenuOwner", wt.HWND),
        ("hwndMoveSize", wt.HWND),
        ("hwndCaret", wt.HWND),
        ("rcCaret", wt.RECT),

    ]

    def __str__(self):
        ret = "\n" + self.__repr__()
        start_format = "\n  {0:s}: "
        for field_name, _ in self. _fields_[:-1]:
            field_value = getattr(self, field_name)
            field_format = start_format + ("0x{1:016X}" if field_value else "{1:}")
            ret += field_format.format(field_name, field_value)
        rc_caret = getattr(self, self. _fields_[-1][0])
        ret += (start_format + "({1:d}, {2:d}, {3:d}, {4:d})").format(self. _fields_[-1][0], rc_caret.top, rc_caret.left, rc_caret.right, rc_caret.bottom)
        return ret


def main(*argv):
    window_name = "Untitled - Notepad"
    hwnd = wgui.FindWindowEx(wcon.NULL, 0, wcon.NULL, window_name)
    print("'{0:s}' window handle: 0x{1:016X}".format(window_name, hwnd))
    tid, pid = wproc.GetWindowThreadProcessId(hwnd)
    print("PId: {0:d}, TId: {1:d}".format(pid, tid))

    user32_dll = ct.WinDLL("user32.dll")
    GetGUIThreadInfo = getattr(user32_dll, "GetGUIThreadInfo")
    GetGUIThreadInfo.argtypes = [wt.DWORD, ct.POINTER(GUITHREADINFO)]
    GetGUIThreadInfo.restype = wt.BOOL

    gti = GUITHREADINFO()
    gti.cbSize = ct.sizeof(GUITHREADINFO)
    res = GetGUIThreadInfo(tid, ct.byref(gti))
    print("{0:s} returned: {1:d}".format(GetGUIThreadInfo.__name__, res))
    if res:
        print(gti)


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main(*sys.argv[1:])
    print("\nDone.")

Вывод :

e:\Work\Dev\StackOverflow\q059884688>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32

'Untitled - Notepad' window handle: 0x00000000042B20D8
PId: 37192, TId: 53072
GetGUIThreadInfo returned: 1

<__main__.GUITHREADINFO object at 0x0000022649436648>
  cbSize: 0x0000000000000048
  flags: 0
  hwndActive: None
  hwndFocus: None
  hwndCapture: None
  hwndMenuOwner: None
  hwndMoveSize: None
  hwndCaret: None
  rcCaret: (0, 0, 0, 0)

Done.

Примечания :

  • печать данных, с которыми вы работаете, поскольку они могут отличаться от ожидаемых. Например, заголовок окна Notepad не является " notepad ", как ваш код ожидает от него, и в этом случае win32 gui .indWindowEx вернется NULL (0).
  • Я также использую [ActiveState.Docs]: документация PyWin32 (она старая и устаревшая, но в большинстве случаев очень полезная)
...