This is a very simple program, it should just open a window but for some reason CreateWindowEx fails (returns 0). I tried to call GetLastError to find the source of the problem and it returned zero as well (no error)! Any suggestions would be greatly appreciated!

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\gdi32.lib

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
Fatal PROTO

.data
g_AppName db "My First App",0
g_ClassName db "SimpleWindowClass",0
g_MainWndClass WNDCLASSEX <SIZEOF WNDCLASSEX,CS_HREDRAW or CS_VREDRAW,OFFSET WndProc,0,0,,,,,0,OFFSET g_ClassName,>

.data?
g_hInstance HINSTANCE ?
g_lpCmdLine LPSTR ?

.code
start:
; setup and call WinMain
invoke GetModuleHandle,0
mov g_hInstance,eax
invoke GetCommandLine
mov g_lpCmdLine,eax
invoke WinMain,g_hInstance,0,g_lpCmdLine,0

; exit
invoke ExitProcess,0

WinMain PROC hInst:HINSTANCE,hPrev:HINSTANCE,lpCmdLine:LPSTR,nCmdShow:DWORD
? ? ? LOCAL hMainWnd:HWND
? ? ? LOCAL msg:MSG
? ? ?
? ? ? ; fill in g_MainWndClass
? ? ? push g_hInstance
? ? ? pop g_MainWndClass.hInstance
? ? ? invoke GetStockObject,WHITE_BRUSH
? ? ? mov g_MainWndClass.hbrBackground,eax
? ? ? invoke LoadIcon,0,IDI_APPLICATION
? ? ? mov g_MainWndClass.hIcon,eax
? ? ? mov g_MainWndClass.hIconSm,eax
? ? ? invoke LoadCursor,0,IDC_ARROW
? ? ? mov g_MainWndClass.hCursor,eax

? ? ? ; open main window
? ? ? invoke RegisterClassEx,ADDR g_MainWndClass
? ? ? .IF (!ax)
? ? ? ? ? ? invoke Fatal
? ? ? ? ? ? ret
? ? ? .ENDIF
? ? ? invoke CreateWindowEx,0,OFFSET g_ClassName,OFFSET g_AppName,WS_OVERLAPPED,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hInst,0
? ? ? .IF (!eax)
? ? ? ? ? ? invoke Fatal
? ? ? ? ? ? ret
? ? ? .ENDIF
? ? ? mov hMainWnd,eax
? ? ? invoke ShowWindow,hMainWnd,0
? ? ? invoke UpdateWindow,hMainWnd

? ? ? .WHILE 1
? ? ? ? ? ? invoke GetMessage,ADDR msg,0,0,0
? ? ? ? ? ? .BREAK .IF (!eax)
? ? ? ? ? ? invoke TranslateMessage,ADDR msg
? ? ? ? ? ? invoke DispatchMessage,ADDR msg
? ? ? .ENDW

? ? ? mov eax,msg.wParam
? ? ? ret
WinMain ENDP

WndProc PROC hwnd:HWND,uMsg:UINT,wparam:WPARAM,lparam:LPARAM
? ? ? .IF (uMsg==WM_DESTROY)
? ? ? ? ? ? invoke PostQuitMessage,0
? ? ? .ELSE
? ? ? ? ? ? invoke DefWindowProc,hwnd,uMsg,wparam,lparam
? ? ? .ENDIF
? ? ? xor eax,eax
? ? ? ret
WndProc ENDP

Fatal PROC
? ? ? LOCAL lpBuffer:DWORD
? ? ? LOCAL errno:DWORD
? ? ? invoke GetLastError
? ? ? mov errno,eax
? ? ? invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,0,errno,0,ADDR lpBuffer,0,0
? ? ? invoke MessageBox,0,lpBuffer,0,MB_OK or MB_ICONINFORMATION
? ? ? invoke LocalFree,lpBuffer
? ? ? ret
Fatal ENDP
Posted on 2005-05-05 19:58:53 by wildgnu
Tough one, but I found it... happened to me before ;)

You missed the ret after invoke DefWindowProc,hwnd,uMsg,wparam,lparam

Also you never show the window. You use: invoke ShowWindow,hMainWnd,0 and 0 equals SW_HIDE.

J.

Posted on 2005-05-05 20:49:59 by JimmyClif
Thanks for noticing! For some reason I thought the mCmdShow argument of ShowWindow was semi-meaningless.

But wait I thought I did put a ret after invoke DefWindowProc!

WndProc PROC hwnd:HWND,uMsg:UINT,wparam:WPARAM,lparam:LPARAM
      .IF (uMsg==WM_DESTROY)
            invoke PostQuitMessage,0
      .ELSE
            invoke DefWindowProc,hwnd,uMsg,wparam,lparam
      .ENDIF
      xor eax,eax
      ret ; <<<<<<<<<<<<<<<<<<<<
WndProc ENDP


Are you saying this isn't good enough?

Sure enough I get the same strange error if I don't put a ret inside the .ELSE block. What gives?
Posted on 2005-05-05 21:27:07 by wildgnu
Oh wait, duh. I get it! WndProc needs to return whatever DefWindowProc returns. So am I do understand that CreateWindowEx calls my WndProc and that by failing to return the proper value this caused CreateWindowEx to think it was in an error condition even though there was no error condition?
Posted on 2005-05-05 21:38:00 by wildgnu
Ok stupid question: how come my window doesn't have a close box?
Posted on 2005-05-05 21:57:17 by wildgnu
Never mind, figured it out!
Posted on 2005-05-05 21:59:46 by wildgnu
An additional note: on Win9x, there's a lot of cases where GetLastError doesn't return meaningful values, especially after GDI calls.
Posted on 2005-05-06 01:29:29 by f0dder

An additional note: on Win9x, there's a lot of cases where GetLastError doesn't return meaningful values, especially after GDI calls.

...and messages to common controls too.
Posted on 2005-05-06 14:12:36 by QvasiModo
Yet another reason why you shouldn't use 9x as a development platform, I guess :)
Posted on 2005-05-06 14:50:29 by f0dder