在Python ctypes中将结构传递给Windows API
我正在尝试在Windows 7的一个应用程序中设置SysDateTimeObject的日期。我使用的是Python 2.7和ctypes库,下面的代码是用来向SysDateTimeObject发送一个DTM_SETSYSTEMTIME消息的:
from ctypes import *
from ctypes.wintypes import BOOL,HWND,RECT,LPCSTR,UINT,INT,DWORD,WORD
import sys
import time
class SYSTEMTIME(Structure):
_fields_=[('wYear',WORD),
('wMonth',WORD),
('wDayOfWeek',WORD),
('wDay',WORD),
('wHour',WORD),
('wMinute',WORD),
('wSecond',WORD),
('wMilliseconds',WORD)]
self.user32 = windll.user32
my_time=SYSTEMTIME(2035,0,0,0,0,0,0,0)
self.user32.SendMessageW(window,c_uint(0x1002),0,byref(my_time))
这里的window是指向正确的SysDateTimeObject的句柄,而0x1002是DTM_SETSYSTEMTIME消息的代码。SendMessageW的第三个参数是一个常量,用来启用或禁用日期时间控件。我可以把它设置为1,这样就会禁用这个控件,正如预期的那样。第四个参数是一个指向已填充的SYSTEMTIME结构的指针。不过,按照上面的写法,它似乎没有任何效果。我可以发送其他消息,但当一个函数需要指向结构的指针时,事情就开始出问题了。我是不是在使用ctypes时搞错了?
1 个回答
1
我在使用 pywinauto 的时候遇到了一些问题,但我找到了办法解决。问题的原因是你试图在一个不同的进程中运行代码,而你的 SYSTEMTIME
结构体却在你自己进程的私有内存空间里。因此,每当它尝试处理这个传递过来的结构体时,就会失败——因为没有权限访问。要解决这个问题,你需要一个远程内存块。
pywinauto.controls.common_controls._RemoteMemoryBlock
就是用来做这个的。
最终的效果是你会写出这样的代码:
remote_mem = common_controls._RemoteMemoryBlock(window)
remote_mem.Write(my_time)
user32.SendMessageW(window, win32defines.DTM_SETSYSTEMTIME,
win32defines.GDT_VALID, remote_mem)
如果你需要使用 DTM_GETSYSTEMTIME,那么在 SendMessage 调用之后,你应该加上 my_time = remote_mem.Read(my_time)
。