프로그램이 제대로 컴파일되지만 기본 창을 만들지 못합니다. 특히 CreateWindowEx
이 실패하고 "창을 만들지 못했습니다."라는 메시지가 인쇄됩니다.Windows API 및 x86 어셈블리를 사용하여 기본 창을 만들지 못했습니다.
내가 뭘 잘못하고 있는지 알 수 있습니까? 나는 조립에 관한 Kip Irvine의 책을 거의 정확하게 따라 가고 있지만, 나는 뭔가를 놓치고있는 것 같다.
편집 : 권장 사항을 기반으로 코드를 업데이트했습니다. 이제 프로그램에서 창 클래스를 등록하지 못하고 "Parameter is incorrect"라는 특정 오류가 발생합니다. 내 WNDCLASSEX
구조체의 매개 변수를 살펴 보았지만 잘못 입력하지는 못했습니다.
EDIT2 : WNDCLASS
및 RegisterClass
에서 "Ex"를 제거 했으므로 창이 나타나고 정상적으로 작동합니다. 그래서 그것은 masm32rt 라이브러리의 구조체와 함수의 이상한 재정의 또는 모순의 일종이라고 생각합니까?
INCLUDE \masm32\include\masm32rt.inc
.data
windowName BYTE "ASM Windows App",0
className BYTE "ASMWin",0
MainWinClass WNDCLASSEX <NULL,CS_HREDRAW + CS_VREDRAW,WinProc,NULL,NULL,NULL,NULL,NULL,COLOR_WINDOW+1,NULL,className,NULL>
windowHandle DWORD ?
hInstance DWORD ?
.code
WinMain PROC
; Get a handle to the current process.
INVOKE GetModuleHandle, NULL
mov hInstance, eax
mov MainWinClass.hInstance, eax
; Check if the handle was received.
.IF eax == 0
pushad
print "Failed to get handle on current process"
popad
call ErrorHandler
jmp ExitProgram
.ENDIF
; Load the program's icon and cursor.
INVOKE LoadIcon, NULL, IDI_APPLICATION
mov MainWinClass.hIcon, eax
INVOKE LoadCursor, NULL, IDC_ARROW
mov MainWinClass.hCursor, eax
; Create the window class.
INVOKE RegisterClassEx, ADDR MainWinClass
; Check if the class was registered.
.IF eax == 0
pushad
print "Failed to register class."
popad
call ErrorHandler
jmp ExitProgram
.ENDIF
; Create the window.
INVOKE CreateWindowEx, 0, ADDR className, ADDR windowName, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL
; Check if window was created successfully.
.IF eax == 0
pushad
print "Failed to create window"
popad
call ErrorHandler
jmp ExitProgram
.ENDIF
; Save the window handle and use it to show the window.
mov windowHandle, eax
INVOKE ShowWindow, windowHandle, SW_SHOW
INVOKE UpdateWindow, windowHandle
; Message Loop
;MessageLoop:
; INVOKE GetMessage, ADDR msg, NULL, NULL, NULL
; INVOKE DispatchMessage, ADDR msg
; jmp MessageLoop
ExitProgram:
;CALL ReadChar
INVOKE ExitProcess, 0
WinMain ENDP
; Window Procedure
WinProc PROC,
hWnd:DWORD, localMsg:DWORD, wParam:DWORD, lParam:DWORD
mov eax, localMsg
.IF eax == WM_CREATE
;call WriteString
jmp WinProcExit
.ELSEIF eax == WM_CLOSE
;call WriteString
jmp WinProcExit
.ELSE
;call WriteString
INVOKE DefWindowProc, hWnd, localMsg, wParam, lParam
jmp WinProcExit
.ENDIF
WinProcExit:
ret
WinProc ENDP
ErrorHandler PROC
.data
pErrorMsg DWORD ?
messageID DWORD ?
.code
INVOKE GetLastError
mov messageID, eax
; Get the corresponding message string.
INVOKE FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER + \
FORMAT_MESSAGE_FROM_SYSTEM,NULL,messageID,NULL,
ADDR pErrorMsg,NULL,NULL
; Display the error message.
INVOKE MessageBox, NULL, pErrorMsg, NULL,
MB_ICONERROR+MB_OK
; Free the error message string.
INVOKE LocalFree, pErrorMsg
ret
ErrorHandler ENDP
END WinMain
주 창을 만드는 데 실패했다는 것은 무엇을 의미합니까? 'CreateWindowEx'가 실패하고 프로그램이'창을 만들지 못했습니다 '를 출력합니까? 아니면 아무 것도 출력하지 않고 어떤 창이 나타나지 않습니까? –
@RossRidge CreateWindowEx가 실패하고 "창을 만들지 못했습니다."라는 메시지가 인쇄됩니다. 나는 그것을 분명히 할 것입니다. – Artekis
DefWindowProc 호출을 잊어 버렸습니다. –