如何将C语言中的结构转换为pywin32?
我正在尝试通过 SendMessage
使用 TTM_GETTEXT
,这是在 pywin32 中的一个功能。问题是,lparam
的结构需要是 TOOLINFO
,这个结构在 MSDN 上有详细的说明,但在 pywin32 中没有对应的实现。我想知道有没有办法用 Python 和 pywin32 创建相同的结构?
编辑:这是我用 ctypes
写的代码。我为 TOOLINFO
创建了一个 Structure
,然后从中生成一个缓冲区,以便传递给 pywin32 的 SendMessage
,最后又把它转换回 TOOLINFO
的 ctypes
Structure
。唯一的问题是,这个方法没有成功:
# My TOOLINFO struct:
class TOOLINFO(Structure):
_fields_ = [("cbSize", UINT),
("uFlags", UINT),
("hwnd", HWND),
("uId", POINTER(UINT)),
("rect", RECT),
("hinst", HINSTANCE),
("lpszText", LPWSTR),
("lpReserved", c_void_p)]
# send() definition from PythonInfo wiki FAQs
def send(self):
return buffer(self)[:]
ti = TOOLINFO()
text = ""
ti.cbSize = sizeof(ti)
ti.lpszText = text # buffer to store text in
ti.uId = pointer(UINT(wnd)) # wnd is the handle of the tooltip
ti.hwnd = w_wnd # w_wnd is the handle of the window containing the tooltip
ti.uFlags = commctrl.TTF_IDISHWND # specify that uId is the control handle
ti_buffer = send(ti) # convert to buffer for pywin32
del(ti)
win32gui.SendMessage(wnd, commctrl.TTM_GETTEXT, 256, ti_buffer)
ti = TOOLINFO() # create new TOOLINFO() to copy result to
# copy result (according to linked article from Jeremy)
memmove(addressof(ti), ti_buffer, sizeof(ti))
if ti.lpszText:
print ti.lpszText # print any text recovered from the tooltip
文本没有被打印出来,但我认为它应该包含我想从工具提示中提取的文本。我在使用 ctypes
的时候是不是哪里出错了?我很确定我的 wnd
和 w_wnd
的值是正确的,所以我一定是做错了什么。
1 个回答
1
这虽然看起来不太美观,但你可以使用 struct 模块把字段打包成一个字符串,并且可以设置合适的字节序、对齐方式和填充。这个过程有点复杂,因为你需要用一个格式字符串来定义结构,格式字符串里只能用对应的基本数据类型,并且要按正确的顺序排列。
你也可以使用 ctypes 来定义结构类型,或者直接与 DLL 进行交互(而不是使用 pywin32)。ctypes 的结构定义更接近 C 语言的定义,所以你可能会觉得这样更好用。
如果你选择在使用 pywin32 的同时使用 ctypes 来定义结构,下面的链接可以给你一些关于如何将结构序列化为字符串的提示: 如何使用 ctypes 进行打包和解包 (结构 <-> 字符串)