Python SetWindowLongW&;错误1413
我试图通过python和ctypes设置Win32 windows的所有者(而不是父级) 当我打电话时:Python SetWindowLongW&;错误1413,python,winapi,ctypes,Python,Winapi,Ctypes,我试图通过python和ctypes设置Win32 windows的所有者(而不是父级) 当我打电话时: GWL_HWNDPARENT = -8 ctypes.windll.user32.SetWindowLongW(hWndChild, GWL_HWNDPARENT, hWndParent) 它失败并且ctypes.GetLastError()返回1413-ERROR\u INVALID\u INDEX() hWndChild和hWndParent似乎都有效,因为我可以成功地使用ctypes
GWL_HWNDPARENT = -8
ctypes.windll.user32.SetWindowLongW(hWndChild, GWL_HWNDPARENT, hWndParent)
它失败并且ctypes.GetLastError()
返回1413-ERROR\u INVALID\u INDEX()
hWndChild和hWndParent似乎都有效,因为我可以成功地使用ctypes.windell.user32.SetParent
我很困惑。无效索引指的是什么
根据评论更新 这需要两个记事本编辑实例,分别是
OwnerWindow.txt
和NonOwnerWindow.txt
import ctypes
GWL_HWNDPARENT = -8
_FindWindow = ctypes.windll.user32.FindWindowW
_FindWindow.argtypes = [ctypes.c_wchar_p,ctypes.c_wchar_p]
_FindWindow.restype = ctypes.c_void_p
_SetWindowLong = ctypes.windll.user32.SetWindowLongW
_SetWindowLong.argtypes = [ctypes.c_long, ctypes.c_long, ctypes.c_long]
_SetWindowLong.restype = ctypes.c_void_p
oHWnd = _FindWindow('Notepad', 'OwnerWindow.txt - Notepad')
nHWnd = _FindWindow('Notepad', 'NonOwnerWindow.txt - Notepad')
print "Last Error: {0}".format(str(ctypes.GetLastError()))
_SetWindowLong(ctypes.c_int(nHWnd), ctypes.c_int(GWL_HWNDPARENT), ctypes.c_int(oHWnd))
print "Last Error: {0}".format(str(ctypes.GetLastError()))
编辑:考虑到@eryksun的评论,我做了一些测试并(重新)阅读了文档 知道调用是否失败或成功的唯一方法是在调用前使用
SetLastError(0)
,然后在调用后使用GetLastError
,如果调用返回0
如果函数成功,则返回值为
指定的32位整数
如果函数失败,则返回值为零。获取扩展错误
信息,请调用GetLastError
如果指定的32位整数的上一个值为零,则
函数成功,返回值为零,但函数未成功
清除最后的错误信息。这使得很难确定
成功或失败。要处理此问题,应清除最后一个错误
在调用之前使用0调用SetLastError以获取信息
SetWindowLong。然后,功能故障将通过返回指示
值为零,GetLastError结果为非零
如果ctypes
中的C/C++代码确实在SetLastError
调用和最后的SetWindowLong
调用之间插入了Win32 API调用,则无法知道是成功还是失败
ctypesuse\u last\u error
示例:
from ctypes import *
from ctypes.wintypes import *
from ctypes import _SimpleCData
user32le = WinDLL('user32', use_last_error=True)
user32le.SetWindowLongW.restype = LONG
user32le.SetWindowLongW.argtypes = [HWND, c_int, LONG]
LONG_PTR = HWND # should be an integer, but a pointer is simpler
if sizeof(HWND) == sizeof(c_long): # WIN32
# WIN32: this is a macro in winuser.h
user32le.SetWindowLongPtrW = user32le.SetWindowLongW
elif sizeof(HWND) == sizeof(c_longlong): # WIN64
user32le.SetWindowLongPtrW.restype = LONG_PTR
user32le.SetWindowLongPtrW.argtypes = [HWND, c_int, LONG_PTR]
def SetWindowLongPtr(hWnd, nIndex, dwNewLong):
if isinstance(dwNewLong, _SimpleCData):
# avoid ArgumentError with LONG, etc
dwNewLong = dwNewLong.value
# set last_error to 0, and save the previous value
last_error = set_last_error(0)
try:
# ctypes calls GetLastError / SetLastError to swap
# LastError and last_error
result = user32le.SetWindowLongPtrW(hWnd, nIndex, dwNewLong)
# ctypes again swaps LastError and last_error
finally:
last_error = set_last_error(last_error)
if not result and last_error:
raise WinError(last_error)
return result
它是一个64位进程,需要使用
SetWindowLongPtrW
?或者hWndChild
实际上是一个子窗口,它可以有父窗口,但不能有所有者?您可以检查其中一个是否为子窗口:ischild=lambda hwnd:bool(GetWindowLongW(hwnd,GWL_样式)&WS_child)
,其中GWL_样式==-16
和WS_child==0x40000000
。根据潜在所有者的子状态,请参阅;快进到幻灯片29,查看感兴趣的部分@eryksun是正确的,我应该询问平台和子窗口的状态,我假设两者都是子窗口(不好)。请编辑您的问题,告诉我们您的两个窗口是子窗口还是顶级窗口@manuell两个窗口都是顶级窗口;如果我使用记事本的两个单独实例,我仍然会遇到1413错误。@E.Beach如果我尝试使用两个顶级HWND,我会得到87(无效参数)。为了得到1413,我必须通过FUNKY索引,因为3548(WinAPI生前的C++)使用<代码> SETHORMON/<代码>,如果这是您需要的,但是在USER32中没有<代码> SetOwner <代码>函数。如果父级是桌面(即顶级窗口),则获取和设置GWL_hwndprent
实际上应用于窗口数据结构中的所有者字段,而不是父级字段。ReactOS是我能获得的最接近“源”链接的SetWindowLongW
调用NtUserSetWindowLong
,它在ReactOS中调用。如果父对象是桌面,则在第3710行调用IntSetOwner
。类似地,GetWindowLongW
调用,如果父对象是桌面,则返回所有者。@eryksun-Yes。新旧事物之间的联系非常清楚。子窗口有父窗口,但没有所有者。“非子”窗口没有父窗口,但可能有所有者。使用SetParent
设置子窗口的父窗口,并可用于设置“非子”窗口的所有者。@eryksun的python/ctypes不够流利,无法编辑带有上一条注释的答案。如果您愿意,可以随意操作。它没有解释1413错误,但是它演示了如何使用SetWindowLong/SetWindowLongPtr。谢谢