Winapi CreateWindowEx失败,出现错误1400
标题说明了一切。我只是尝试在汇编中使用CreateWindowEx创建一个窗口,调用失败,出现错误1400(错误的窗口句柄)。我已经验证了没有其他API调用失败,并且DefWindowProc为WM_CREATE返回0(通过)。创建WindowEx的参数在我看来是正确的 编辑:现在与错误检查共享代码,我以前为了可读性删除了这些代码Winapi CreateWindowEx失败,出现错误1400,winapi,nasm,Winapi,Nasm,标题说明了一切。我只是尝试在汇编中使用CreateWindowEx创建一个窗口,调用失败,出现错误1400(错误的窗口句柄)。我已经验证了没有其他API调用失败,并且DefWindowProc为WM_CREATE返回0(通过)。创建WindowEx的参数在我看来是正确的 编辑:现在与错误检查共享代码,我以前为了可读性删除了这些代码 extern __imp__GetModuleHandleA@4 extern __imp__RegisterClassA@4 extern __imp__ExitP
extern __imp__GetModuleHandleA@4
extern __imp__RegisterClassA@4
extern __imp__ExitProcess@4
extern __imp__AdjustWindowRect@12
extern __imp__CreateWindowExA@48
extern __imp__GetSystemMetrics@4
extern __imp__GetLastError@0
extern __imp__DefWindowProcA@16
global _main
section main text align=1
_main:
push byte 0
call [__imp__GetModuleHandleA@4]
test eax, eax
jz OnError
mov dword [hInstance], eax
push dword wndclass
call [__imp__RegisterClassA@4]
test eax, eax
jz OnError
; WS_VISIBLE | WS_CAPTION | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_SYSMENU
mov ebx, 0x10000000 | 0x00C00000 | 0x04000000 | 0x02000000 | 0x00080000
push byte 0
push ebx
push rect
call [__imp__AdjustWindowRect@12]
test eax, eax
jz OnError
push byte 0
push dword [hInstance]
push byte 0
push byte 0
; rect.bottom - rect.top
mov eax, dword [rect.bottom]
sub eax, dword [rect.top]
push eax
; rect.right - rect.left
mov eax, dword [rect.right]
sub eax, dword [rect.left]
push eax
; ( GetSystemMetrics(SM_CYSCREEN) - rect.bottom + rect.top ) >> 1
push byte 1 ; SM_CYSCREEN
call [__imp__GetSystemMetrics@4]
sub eax, dword [rect.bottom]
add eax, dword [rect.top]
sar eax, 1
push eax
; ( GetSystemMetrics(SM_CXSCREEN) - rect.right + rect.left ) >> 1
push byte 0 ; SM_CXSCREEN
call [__imp__GetSystemMetrics@4]
sub eax, [rect.right]
add eax, [rect.left]
sar eax, 1
push eax
push ebx ; dwStyle
push byte 0 ; lpWindowName
push classname ; lpClassName
push 0x00040000 | 0x00000100 ; dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE
call [__imp__CreateWindowExA@48]
test eax, eax
jz OnError
push byte 0
call [__imp__ExitProcess@4]
OnError:
call [__imp__GetLastError@0]
push eax
call [__imp__ExitProcess@4]
section WinProc text align=1
WinProc:
push dword [esp + 20]
push dword [esp + 16]
push dword [esp + 12]
push dword [esp + 8]
call [__imp__DefWindowProcA@16]
ret 16
section wndclass data align=1
wndclass:
dd 0x0020 | 0x0002 | 0x0001 ; Style CS_OWNDC | CS_HREDRAW | CS_VREDRAW
dd WinProc ; lpfnWndProc
dd 0 ; cbClsExtra
dd 0 ; cbWndExtra
hInstance:
dd 0 ; hInstance
dd 0 ; hIcon
dd 0 ; hCursor
dd 0 ; hbrBackground
dd 0 ; lpszMenuName
dd classname ; lpszClassName
classname:
db '1337Class', 0
section rect data align=1
rect:
.left: dd 0
.top: dd 0
.right: dd 1366
.bottom: dd 768
原来问题出在我的窗口程序上。完全搞砸了。仅调用DefWindowProc的工作窗口过程的一个好例子是
WinProc:
mov ebp, esp
push dword [ebp + 16]
push dword [ebp + 12]
push dword [ebp + 8]
push dword [ebp + 4]
call [__imp__DefWindowProcA@16]
ret 16
经验教训:
我不知道,但可能是a)
推送字节0
实际上推送一个字节,而不是dword,或者b)ebx
正在被删除。您需要进行调试,以查看两者是否都有可能。如果两者都没有,那么IDK,对不起。推送字节0
肯定推送一个dword,ebx是调用方保存,所以它不会被删除。感谢您的回复。*来电保存。我总是搞砸。我看到的一个问题是,在传递RegisterClassA()
结构之前,没有将hInstance
分配给WNDCLASSA
结构。您正在将hInstance
分配给EBX
寄存器,但之后不处理该寄存器。但是,您正在将hInstance
传递到CreateWindowEx()
。所以你有一个错配。好眼力mov-eax,dword[hInstance]
应该是mov-dword[hInstance],eax
(我讨厌在英特尔和AT&T语法之间切换)。不幸的是,它没有解决问题。3-不,不是这样,除非是在(非)幸运的情况下。