【问题标题】:GetGUIThreadInfo() with pywin32GetGUIThreadInfo() 与 pywin32
【发布时间】:2020-05-10 02:05:17
【问题描述】:

我正在尝试关注this answer,我已经到了应该打电话的地步

GetGUIThreadInfo()

但我在我使用的pywin32 docomentation 中找不到。

到目前为止我所做的是

import win32api
import win32gui
import win32process

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

但最后一行是完整的,因为我找不到调用函数的正确方法。

更新1:

我认为我取得了一些进展,但现在我的结构在我期望一些 hwnd 时返回 0...所以也许我的结构没有被写入,我认为这可能是因为我的结构中的类型,但我如何找到正确的类型?

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)

更新2:

我找到了here的类型

更新3:

如果有人想看看我用这个做什么去看看here

【问题讨论】:

    标签: python python-3.x windows ctypes pywin32


    【解决方案1】:

    显然,[MS.Docs]: GetGUIThreadInfo function 没有被 PyWin32 包裹,因此必须使用替代方法。其中之一是通过[Python 3.Docs]: ctypes - A foreign function library for 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”,在这种情况下 win32gui.FindWindowEx 会返回 (0)。
    • 我也使用[ActiveState.Docs]: PyWin32 Documentation(它已经过时了,但在大多数情况下它非常有用)

    【讨论】:

    • @sth0r:这回答了你的问题吗?如果是,请接受答案,以便其他人也能够承认([SO]: What should I do when someone answers my question?)。如果没有,请告诉我如何改进它,所以它会回答它。
    • 我可以两者都做吗?它确实解决了问题,但我不明白解决方案的部分内容,我想将它变成一个以 hwnd 作为输入并返回 hwndFocus 的函数,但我不想要答案,但可能要求澄清一下
    • 我真的不明白这是做什么的? GetGUIThreadInfo = getattr(user32_dll, "GetGUIThreadInfo")
    • 当某事物将 self 作为输入时,这意味着什么?
    • 回答第一条评论:它在加载的 .dll 实例中搜索具有给定名称的函数。但它包含在 CTypes URL 中(在答案中)。至于第二条评论:查看docs.python.org/3/tutorial/classes.html
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多