News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

CreateWindowEx fails with ERROR_SUCCESS

Started by Zaerion, January 06, 2011, 08:04:18 PM

Previous topic - Next topic

Zaerion

just had a weird thing happen. RegisterClassEx returns successful, but when i call CreateWindowEx it returns 0 and when i call GetLastError, it shows the last error was ERROR_SUCCESS...


.code
start:
invoke                               GetModuleHandle,NULL
mov                                  hInstance,eax
invoke                               GetCommandLine
mov                                  CommandLine,eax
invoke                               WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke                               ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL                               wc:WNDCLASSEX
LOCAL                               msg:MSG
LOCAL                               hwnd:HWND

; register our class so we can create our main window
mov                                  wc.cbSize,SIZEOF WNDCLASSEX
mov                                  wc.style,NULL
mov                                  wc.lpfnWndProc,OFFSET WndProc
mov                                  wc.cbClsExtra,NULL
mov                                  wc.cbWndExtra,NULL
push                                 hInstance
pop                                  wc.hInstance
mov                                 wc.hbrBackground,COLOR_WINDOW+1
mov                                 wc.lpszMenuName,NULL
mov                                 wc.lpszClassName,OFFSET WinClass
invoke                              LoadIcon,NULL,IDI_APPLICATION
mov                                 wc.hIcon,eax
mov                                 wc.hIconSm,eax
invoke                              LoadCursor,NULL,IDC_ARROW
mov                                 wc.hCursor,eax

invoke                              RegisterClassEx,addr wc
.IF                                   (eax==0)
invoke                      MessageBox,NULL,ADDR RegisterClassError,ADDR MsgBoxTitle,MB_OK or MB_ICONERROR
invoke                      ExitProcess,eax
.ENDIF

invoke                              CreateWindowEx,NULL,ADDR WinClass,NULL,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInst,NULL
.IF                                   (eax==0)
invoke                      MessageBox,NULL,ADDR CreateWindowError,ADDR MsgBoxTitle,MB_OK or MB_ICONERROR
invoke                      ExitProcess,eax
.ENDIF

mov                                 hwnd,eax
mov                                 AppHwnd,eax
invoke                              ShowWindow,hwnd,SW_HIDE
invoke                              UpdateWindow,hwnd

; main message dispatch loop
.WHILE                            TRUE
invoke                      GetMessage,ADDR msg,NULL,NULL,NULL
.BREAK .IF                (!eax)
invoke                     TranslateMessage,ADDR msg
invoke                     DispatchMessage,ADDR msg
.ENDW

mov                                eax,msg.wParam
ret
WinMain endp

dedndave

not sure if the lpWindowName can be NULL - you might be able to point to a null string, though
that is because the registered style has a title bar - i think it needs a string of some sort

Tight_Coder_Ex

Give you window a style, WS_OVERLAPPEDWINDOW (0) does not work on NT systems, but I do believe it worked on 95 and 98

donkey

Tight_Coder_Ex,

WS_OVERLAPPEDWINDOW works fine on all systems

dedndave,

lpWindowName can be NULL

Zaerion,

Let us see your WM_CREATE handler. WM_CREATE is a special message that is not handled the same as others by the normal dispatcher. If the WM_CREATE message fails a perfectly fine window will cause CreateWindowEx to fail and return NULL but with ERROR_SUCCESS. Of course I am assuming you are not also handling WM_NCCREATE and WM_NCCALCSIZE, which also have special handlers.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

Zaerion

i had not written a handler for the WM_CREATE, WM_NCCREATE, or WM_NCCALCSIZE messages. i did modify it to add a WM_CREATE message to the window procedure, but it still fails. rather than clog up the forum with my code, i'll put a link to the file.

http://www.zaerion.com/temp/ucbtray.zip

i've tried using OllyDbg to see if the CreateWindowEx error was just a symptom of an earlier problem, but everything looks OK to me up until the CreateWindowEx invoke returns a 0.



thanks for the help!

jj2007

When I comment out...
invoke FindWindowEx,NULL,NULL,ADDR UCBClass,NULL
mov UCBHwnd,eax
.IF 0 ;(eax==0)
invoke MessageBox,NULL,ADDR UCBNotFoundError,ADDR MsgBoxTitle,MB_OK or MB_ICONERROR
invoke ExitProcess,eax
.ENDIF


... then CreateWindowEx fails with "file not found".

Gunner

What about the .else statement?  It is missing!  Try adding:

.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret



WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL pt:POINT

.IF uMsg==WM_CREATE
invoke InstallTrayIcon
mov UCBState,0

.ELSEIF uMsg==WM_DESTROY
invoke Shell_NotifyIcon,NIM_DELETE,ADDR NotifyIcon
invoke PostQuitMessage,NULL

.ELSEIF uMsg==WM_COMMAND
mov eax,wParam

.IF ax==EXIT_MENU
invoke Shell_NotifyIcon,NIM_DELETE,ADDR NotifyIcon
invoke PostQuitMessage,NULL

.ELSEIF ax==SHOWHIDE_MENU
.IF UCBState==0 ; UCB window is visible
invoke ModifyMenu,PopupMenu,SHOWHIDE_MENU,MF_STRING,SHOWHIDE_MENU,ADDR ShowMenu
invoke ShowWindow,UCBHwnd,SW_HIDE
mov UCBState,1

.ELSEIF UCBState==1 ; UCB window is hidden
invoke ModifyMenu,PopupMenu,SHOWHIDE_MENU,MF_STRING,SHOWHIDE_MENU,ADDR HideMenu
invoke ShowWindow,UCBHwnd,SW_SHOW
mov UCBState,0
.ENDIF
.ENDIF

.ELSEIF uMsg==MY_TRAYICON
.IF wParam==MY_TRAYID
.IF lParam==WM_RBUTTONDOWN
invoke GetCursorPos,ADDR pt
invoke SetForegroundWindow,AppHwnd
invoke TrackPopupMenu,PopupMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,AppHwnd,NULL
.ENDIF
.ENDIF
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret

.ENDIF

xor eax,eax
ret
WndProc endp


Well it runs with the .else!!  I get this error message:
Quote---------------------------
UCBTray
---------------------------
Could not find the UC for Business Desktop window. Please start it and then re-run UCBTray.
---------------------------
OK   
---------------------------
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

jj2007

The
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
is missing altogether. If you add it, creation works but it still does not show. Add WS_VISIBLE:

invoke CreateWindowEx,0,ADDR WinClass,0,WS_OVERLAPPEDWINDOW or WS_VISIBLE,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInst,NULL

... and a nice blank window appears.

Zaerion

when ii run it after adding the DefWindowProc call, i still get the same error. the UCB Desktop message pops up because the check for that occurs before the CreateWindow call. if you comment out this section:
invoke FindWindowEx,NULL,NULL,ADDR UCBClass,NULL
mov UCBHwnd,eax
.IF (eax==0)
invoke MessageBox,NULL,ADDR UCBNotFoundError,ADDR MsgBoxTitle,MB_OK or MB_ICONERROR
invoke ExitProcess,eax
.ENDIF


you will likely get the same error.

jj2007


Zaerion

ok, i figured out the problem. it was the xor eax,eax at the bottom of the window procedure in addition to not having the DefWindowProc invoke in there.

Zaerion

and when i say i figured it out, i don't mean that i figured it out. you guys pointed out the errors and i just corrected it in my code and then misspoke.

jj2007

It's called teamwork :thumbu

Re the xor eax, eax, Win32.hlp says:
QuoteThe return value of DefWindowProc is the result of the message processing and depends on the message.
The window proc is a place where we can alter the processing of messages - change a color, return a brush, size a window etc; in 90% of all cases we do not want to change anything, so we just let it drop through the SWITCH umsg code and hand it over to the default procedure. But Windows expects a return value - and if you always return zero via xor eax, eax, then Windows believes that all messages are failing...

Zaerion

yeah, i have win32.hlp and i didn't read it. my bad. :eek

donkey

Quote from: jj2007 on January 06, 2011, 11:28:15 PM
But Windows expects a return value - and if you always return zero via xor eax, eax, then Windows believes that all messages are failing...

Good call, it was most likely the WM_NCCREATE message that was causing the problem then, returning NULL from that will have the same effect as returning -1 from WM_CREATE, NULL handle and ERROR_SUCCESS.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable