Skip to main content
 首页 » 编程设计

python之在 python ctypes 中将结构传递给 Windows API

2025年05月04日9findumars

我正在尝试在 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 的 HWND,0x1002 是 DTM_SETSYSTEMTIME 消息的代码。 SendMessageW 的第三个参数是一个常量,用于启用或禁用 DateTimeControl。我可以将它设置为 1,它将按预期禁用控件。第四个参数是指向填充的 SYSTEMTIME 结构的指针。但是,它似乎没有像上面写的那样做任何事情。我能够发送其他消息,但是当一个函数需要一个指向结构的指针时,事情就开始失败了。我在这里使用的 ctypes 有误吗?

请您参考如下方法:

我正在使用 pywinauto并遇到了这个需求并设法解决了它。问题的原因是你试图在不同的进程中运行它,而你的 SYSTEMTIME 结构在你自己进程的私有(private)内存空间中。因此,每当它试图对传递的结构做任何事情时,它都会失败——访问被拒绝。您需要一个远程内存块来解决问题。

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)。