Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SetWindowLongW&;错误1413_Python_Winapi_Ctypes - Fatal编程技术网

Python SetWindowLongW&;错误1413

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

我试图通过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.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调用,则无法知道是成功还是失败

ctypes
use\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。谢谢