News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

error msg?

Started by shankle, June 26, 2012, 12:49:14 AM

Previous topic - Next topic

wjr

Sorry, as you most likely found out, LOCAL hWnd:DWORD and LOCAL hWnd:HANDLE do not work. The corrections for these would be LOCAL hWnd:D and LOCAL hWnd:%HANDLE.

However, since for a 32-bit application a DWORD is the default, this can be simplified to LOCAL hWnd which is better if you plan on going to 64-bit where QWORD is the default (the %HANDLE definition in the header files would also make this switch).

If you get an error, please specify the GoAsm or GoLink error message. I do not get an error using what you originally had for your CreateDC call. If you used a global variable for hWnd, I do not see how that would give an error. Given that you have had some problems with hInst, although CreateWindowExA works, does it return NULL? This is an error condition that you should generally check for, since ShowWindow and the rest are not going to work.


shankle

In my test the CreateWindowEX tests as BAD.
This is the same code I use in my MASM32 version.
Regardless of the test the CreateWindowEX does not work.
No error message from GoAsm but a Window message saying the program
has stopped working. cc:codecode is a struct I defined.

WinMain:
    FRAME hInst,hPrevInst,CmdLine,CmdShow
   LOCAL msg:MSG,rc:RECT,wc:WNDCLASSEXA,cc:codecode,hWnd
; more code which is already mentioned in a prior mesage               

   INVOKE CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
           WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
           [rc.bottom],NULL,NULL,[hInst],NULL       
      mov   [hWnd],eax 
     
;test code begin
;szText             db   ' executed correctly',0
;szText2           db   ' is bad',0
;szCaption       db   'TRUE',0
;szCaption2     db   'FALSE',0
       pusha
          cmp D[eax], 0     ; success
           je >         
             invoke MessageBox, NULL, ADDR szText, ADDR szCaption, MB_OK
           jmp >out1
:             
             invoke MessageBox, NULL, addr szText2, addr szCaption2, MB_OK
out1:             
       popa
;test code end         
 
   INVOKE ShowWindow, [hWnd], SW_SHOWNORMAL
   INVOKE UpdateWindow, [hWnd]
   
; message loop here also mentioned in a prior message   

 

dedndave

rc.right and rc.bottom are screen coordinates
the parameters should be width and height

another potential problem...
the window handle is generally stored in a global variable, rather than a local one
this may not be a problem, if the code is written to always use a local value

shankle

Hi Dave,
The rc.bottom/rc.right are part of the RECT struct.
This worked fine in my MASM32 program.

If anything I would suspect  the trouble is caused by how I have defined  hWnd.
As far as I know I am using a Local definition of hWnd.
This also worked in the MASM32 version.

In answer to WJR the CreateWindowEX does return 0/NULL .
Question is why and what caused it?


dedndave

what value does the WM_CREATE code in WndProc return in EAX ???
WM_CREATE should return 0 to continue creation of the window
if WM_CREATE returns -1, window creation ceases and CreateWindowEx returns 0

also - the message loop must be working properly for WM_CREATE to succeed

at any rate - you can use GetLastError for a general idea of what caused the problem
i am guessing - invalid parameter   :P
or maybe - class not found

also...
window creation causes a myriad of other messages to be sent to WndProc
like getminmaxinfo, paint, ncpaint, geticon - a bunch of em
be sure the structure of WndProc allows unhandled messages to pass to DefWindowProc   :t

wjr

The local hWnd looks good now. Before diving into other messages, to be on the safe side, did you fix your INVOKE WinMain as suggested back in Reply #65? If not, your value in [hInst] will be wrong causing CreateWindowEx to fail.

shankle

I did make the changes requested as seen below:

pCmdline         dd       0

   invoke GetModuleHandleA, NULL
   mov    [hInstance],eax
   invoke GetCommandLine
        mov [pCmdline], eax      
   invoke WinMain, [hInstance],NULL,[pCmdline],SW_SHOWDEFAULT
   invoke ExitProcess,eax

WinMain:
    FRAME hInst,hPrevInst,CmdLine,CmdShow
   LOCAL msg:MSG,rc:RECT,wc:WNDCLASSEXA,cc:codecode,hWnd             

dedndave

       pusha
;
;
;
       popa

PUSHA and POPA push and pop words !!!
use PUSHAD and POPAD to push and pop dword register values

    INVOKE CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
           WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
           [rc.bottom],NULL,NULL,[hInst],NULL     
      mov   [hWnd],eax
.if !eax
invoke GetLastError
invoke MessageBox,0,uhex$(eax),0,0
invoke ExitProcess,0
.endif

dedndave

this code will display the error as a string, rather than a number   :biggrin:

    INVOKE  CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
            WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
            [rc.bottom],NULL,NULL,[hInst],NULL     
    mov     [hWnd],eax
    .if !eax
        INVOKE  GetLastError
        sub     esp,512
        xor     ecx,ecx
        mov     edx,esp
        INVOKE  FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,ecx,eax,ecx,edx,512,ecx
        mov     edx,esp
        xor     ecx,ecx
        INVOKE  MessageBox,ecx,edx,ecx,ecx
        add     esp,512
        INVOKE  ExitProcess,0
    .endif




shankle

Hi Dave,
The "IF" statement in your last message  has to be changed to GoAsm format.
I have no idea how to change "!eax" to GoAsm format. I interpret it as not eax.
Otherwise I would try it.

dedndave

.if !eax means "if not eax" or "if eax is 0"
    INVOKE  CreateWindowEx, NULL,addr szDisplayName,addr AppName,\
            WS_OVERLAPPEDWINDOW,[rc.left],[rc.top],[rc.right],\
            [rc.bottom],NULL,NULL,[hInst],NULL     
    mov     [hWnd],eax
    or      eax,eax
    jnz     around
        INVOKE  GetLastError
        sub     esp,512
        xor     ecx,ecx
        mov     edx,esp
        INVOKE  FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,ecx,eax,ecx,edx,512,ecx
        mov     edx,esp
        xor     ecx,ecx
        INVOKE  MessageBox,ecx,edx,ecx,ecx
        add     esp,512
        INVOKE  ExitProcess,0
around:

shankle

#86
Hi Dave,
Added your code with the small change to conform to GoAsm format.

    cmp D[eax],0
      jnz > around

Maybe this sequence might shed some light on the problem.
I have message boxes at Start, just before CreatWindowEX in winmain and
at the end of WM_CREATE. I have Dave's error code just after the CREATEWINDOWEX.
When I run the program these messagebox messages occur in this order:
Start, WinMain, WM_CREATE, BOMB. The program is supposed to return to
CreatWindowEX after WM_CREATE. Then Dave's error code check would execute
if an error occurred. Instead a windows message occurs stating that the program
has stopped working.

dedndave

QuoteInstead a windows message occurs stating that the program has stopped working.

i hope it says more than that   :P

i would have to guess there is a problem with WndProc
but - it could be the message loop, as well

make sure WndProc is set up correctly, in general:
EBX, EBP, ESI, EDI are preserved (or not destroyed)
the routine pops 4 dword parms when it returns (RET 16)
unhandled messages invoke DefWindowProc and return it's value from EAX

you could put a temporary version of WndProc in there that handles a minimal number of messages
for example - if it just handles WM_CLOSE and WM_DESTROY
at least you can see if a window appears
in fact, all you need is DefWindowProc and a RET (close is nice, though)
    INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam
    ret


you might disassemble the code
sometimes, the problem glares at you from the disassembled code, while the source format hides it

attach the EXE to your next post - i'll have a look

Ryan

Correct me if I'm wrong, but you need to handle WM_DESTROY with a PostQuitMessage, no?  Without it the window will close, but the process will remain running.  DefWindowProc does not do it.

dedndave

yes - that's what i say
but - you can assemble and run without it - then use the task manager to close it

the idea here is a one-time temporary test to see if things are put together right