News:

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

Does RegisterClassEx check for a valid WndProc?

Started by ThoughtCriminal, January 27, 2006, 04:49:08 PM

Previous topic - Next topic

ThoughtCriminal

I'm not sure if my call to RegisterClassEx is failing or not.  I get a non-0 return but when I call GetLastError:

ERROR_INVALID_PARAMETER
87 The parameter is incorrect.

I'm using a dummy proc atm.  All my calls to CreateWindowEx are failing with error:

ERROR_CANNOT_FIND_WND_CLASS
1407 Cannot find window class.

push 0
push 400000h
push 0
push 0
push 80000000h
push 80000000h
push 80000000h
push 80000000h
push 0
push [edi]+((lpszClassName)-eWINC);-------- Both point to a same point as used in WNDCLASSEX. ie pointer to acsiiz string.
push [edi]+((lpszClassName)-eWINC);
push 0

call dword ptr[ebp]+CreateWindow


Been a long time since I last worked on a windowed app.  Been woking hours on trying to get this to work.

Thanks.

MusicalMike

RegisterClassEx takes a pointer to a WNDCLASSEX struct. Pushing the data structure itself won't work.

ThoughtCriminal

What you a looking at are the parameters for CreateWindowExA. Here's my RegisterClassExA:

add edi,(eWINC)-oUS32
push edi        ;<-----------------------------edi quest the address of the top of my WNDCLASSEX struct confimed with correct with debugger.
call dword ptr[ebp]+RegisterClass

;eax = 7ffd0000h  after call

push 0
push 400000h
push 0
push 0
push 80000000h
push 80000000h
push 80000000h
push 80000000h
push 0
push [edi]+((lpszClassName)-eWINC)
push [edi]+((lpszClassName)-eWINC)
push 0

call dword ptr[ebp]+CreateWindow


From the SDK:

If the function fails, the return value is zero

The function is not failing.  What I wonder is if RegisterClassExA runs the WndProc once to check if it is valid?  Perhaps it detecting my WndProc is not valid and thats why GetLastError gives me an invalid parameter warning.  If someone could take a window app of theirs and point the wc.lpfnWndProc to another proc I wonder if they would get the same result.

I'll add a proper WndProc very soon and see if it makes a difference.

This is my WNDCLASSEX struct in case anyone sees something odd:

win.cbSize   0x0000002c   unsigned long
win.style   0x00040020   unsigned long
win.lpfnWndProc   0x00401000   unsigned long
win.cbClsExtra   0x00000000   unsigned long
win.cbWbdExtra   0x00000000   unsigned long
win.hInstance   0x00400000   unsigned long
win.hIcon   0x00000000   unsigned long
win.hCursor   0x00000000   unsigned long
win.hbrBackground   0x00000000   unsigned long
win.lpszMenuName   0x00000000   unsigned long
win.lpszClassName   0x00403100   unsigned long

disassembly if anyone is interested:

add edi,(eWINC)-oUS32 ;// Adjust edi
0040104E 83 C7 BC         add         edi,0FFFFFFBCh
push edi
00401051 57               push        edi 
call dword ptr[ebp]+RegisterClass
00401052 FF 55 14         call        dword ptr [ebp+14h]
call dword ptr[ebp]+GetLastError
00401055 FF 55 08         call        dword ptr [ebp+8]

push 0
00401058 6A 00            push        0   
push 400000h
0040105A 68 00 00 40 00   push        400000h
push 0
0040105F 6A 00            push        0   
push 0
00401061 6A 00            push        0   
push 80000000h
00401063 68 00 00 00 80   push        80000000h
push 80000000h
00401068 68 00 00 00 80   push        80000000h
push 80000000h
0040106D 68 00 00 00 80   push        80000000h
push 80000000h
00401072 68 00 00 00 80   push        80000000h
push 0
00401077 6A 00            push        0   
push [edi]+((lpszClassName)-eWINC)
00401079 FF 77 28         push        dword ptr [edi+28h]
push [edi]+((lpszClassName)-eWINC)
0040107C FF 77 28         push        dword ptr [edi+28h]
push 0
0040107F 6A 00            push        0   

call dword ptr[ebp]+CreateWindow
00401081 FF 55 10         call        dword ptr [ebp+10h]


Thanks.

donkey

Your lpfnWndProc looks suspiciously like the origin of your program (ie entry point) and not a window procedure. No, AFAIK RegisterClassEx does not verify the address, your error will appear when the window of the class is first created and it calls the address you passed. Obviously the return value from RegisterClassEx is not an Atom, it is far larger than 16 bits so I would look at other parameters.
"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

zooba

Quote from: donkey on January 28, 2006, 02:47:02 PM
Your lpfnWndProc looks suspiciously like the origin of your program (ie entry point)

Not necessarily. The entry point doesn't have to be at the start of the text section.

Also, only the lower 16-bits of the return value are important. So effectively the result is 0 which indicates an error.

Personally, I'd include a cursor (just do LoadCursor 0, IDC_ARROW) so you don't have to respond to messages asking which cursor to use.

Finally, the cbSize parameter you're using is too small (by 4). Ensure that you are using 'SIZEOF WNDCLASSEX' to fill that parameter (it evaluates to an immediate so it will just mov in :wink) and not counting the parameters yourself. If you are already using SIZEOF, ensure your WNDCLASSEX structure has the 'hIconSm DWORD ?' member at the end.

Cheers,

Zooba :U

ThoughtCriminal

Thanks for the help.  I fired up Iczelion tutorial #3 and stepped thru it.

I use the website version as referance, but with the small text I  missed: hIconSm DWORD ?

Problems ensued.

Thanks.