Hi,

I have been plucking out my head trying to figure out what caused the CreateWindowEx to fail (return 0 in eax). The error code is ERROR_INVALID_HANDLE, but I do not think that helps because in my other test codes... it returns a valid handle but the same error exist.. My code is as follows..



start:
invoke LoadLibrary,richeditdll
push eax ;For FreeLibrary
invoke WSAStartup,0202h,wsadata
or eax,eax
jnz exit
invoke LoadIcon,0,IDI_APPLICATION
mov [wc.hIcon],eax
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],eax
mov [wc.style],0
mov [wc.lpfnWndProc],WindowProc
mov [wc.cbClsExtra],0
mov [wc.cbWndExtra],0
mov [wc.hInstance],hinstance
mov [wc.hbrBackground],COLOR_WINDOW+1
mov [wc.lpszMenuName],0
mov [wc.lpszClassName],ClassName
invoke RegisterClass,wc
invoke CreateWindowEx, 0, ClassName, AppName, WS_OVERLAPPEDWINDOW,\
0, 0 , 100, 100, NULL, NULL, hinstance, NULL
mov [mainhwnd],eax
invoke ShowWindow, [mainhwnd], SW_SHOWNORMAL
invoke UpdateWindow, [mainhwnd]
msg_loop:
invoke GetMessage,msg,NULL,0,0
or eax,eax
jz exit
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop
exit:
invoke FreeLibrary
invoke ExitProcess,0

PS: the full source code is buggy as I am still trying to convert it from a dialogbox based to windows...

Regards,
Victor
Posted on 2004-03-13 23:34:45 by roticv
Hi Roticv,

Everything looks fine. I do have one suggestion though. Instead of using LoadLibrary to load Riched20.dll, use the inc and lib from masm32 and just include the following line anywhere in your code where it will never be executed:

include riched20.inc

includelib riched20.lib
.code
invoke CreateTextServices,0,0,0

It will force the PELoader to load the DLL then there is no need to load or free the library at all. I use GoAsm so I import the IID_ITextHost2 GUID which resides in the DLL to force load it but since the MASM libs don't handle exported values you can just use the function instead. In GoAsm you have only to do this :

mov eax,
Posted on 2004-03-13 23:58:49 by donkey
Hi donkey,

That's exactly the problem. Because everything seem to look fine, I do noth know what caused the CreateWindowEx to return null.:grin:
Posted on 2004-03-14 00:01:12 by roticv
My guess is your not providing a class style that is typical for windows created as overlapped (as such the CreateWindow expects a parent window):

mov , CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW

All else apears correct...
:NaN:
Posted on 2004-03-14 00:03:19 by NaN
Actually I fixed it. The problem was with my WindowProc. Now I know that WindowProc is called a few times before the return to CreateWindowEx. So in short WM_CREATE is definitely not the first message passed to the window.
Posted on 2004-03-14 00:34:38 by roticv


start:
invoke LoadIcon,0,IDI_APPLICATION
mov [wc.hIcon],eax
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],eax
mov [wc.style],0
mov [wc.lpfnWndProc], offset WindowProc
mov [wc.cbClsExtra],0
mov [wc.cbWndExtra],0
invoke GetModuleHandle, NULL
mov hinstance, eax
mov [wc.hInstance], eax
mov [wc.hbrBackground],COLOR_WINDOW+1
mov [wc.lpszMenuName],0
mov [wc.lpszClassName], offset ClassName
invoke RegisterClass,addr wc
invoke CreateWindowEx, 0, addr ClassName, addr AppName, WS_OVERLAPPEDWINDOW,\
0, 0 , 100, 100, NULL, NULL, hinstance, NULL
mov mainhwnd,eax
invoke ShowWindow, [mainhwnd], SW_SHOWNORMAL
invoke UpdateWindow, [mainhwnd]
msg_loop:
invoke GetMessage,addr msg,NULL,0,0
or eax,eax
jz exit
invoke TranslateMessage,addr msg
invoke DispatchMessage, addr msg
jmp msg_loop
exit:
invoke ExitProcess,0


The above is a subset of my code!

As far as I can tell, you weren't passing the addresses of functions and variables, instead literal values. The code ran fine for me once I had changed some of your values. I don't know what assembler you were using, I used MASM, also, where are you getting the process handle passed to your application in the wc.hInstance variable?
Posted on 2004-03-14 00:37:54 by SubEvil
WM_NCCREATE if the first message sent to your WindowProc, if you return false from this message CreateWindowEx will fail and return NULL.

Hi Subevil,

The hInstance for a normal app is always 0400000h
Posted on 2004-03-14 00:40:16 by donkey
Hi Subevil,

I am using fasm. I have hardcoded hinstance to be 400000h

Hi donkey,

WM_NCCREATE if the first message sent to your WindowProc, if you return false from this message CreateWindowEx will fail and return NULL.

I guess that is exactly why my CreateWindowEx fails. Learn a thing each day..
Posted on 2004-03-14 00:41:52 by roticv
Damn! Never knew hInstance was always 0400000h! Isn't that a bit risky? Hardcoding things like that? Just now windows changes it in Win64 or something? Anyway, thanx! So I also learnt something new! BTW, are HANDLE's ALWAYS memory locations?
Posted on 2004-03-14 05:16:03 by SubEvil
Hi Subevil,

hinstance points to where the exe is mapped to. For normal exe for which the base address is 400000h, hardcoding it should not be a problem. If you change your base address to something else or you are coding a dll, the histance value will change too.

Take a look at http://www.asmcommunity.net/board/index.php?topic=6225
Quite an interseting discussion on hinstance and 400000h
Posted on 2004-03-14 05:23:27 by roticv
While it holds true on all current win32 versions, there is nothing that says HINSTANCE must be your module load address. It's plain wrong to depend on the value of HANDLEs, they are supposed to be "black box" values. It would be reasonable to use 0x400000 hardcoding and all these assumptions in a 64k demo, but it's a foo foo foo thing to do in production code.

Shame on you, it's not like a GetModuleHandle() call is a big waste of instructions.
Posted on 2004-03-14 06:15:25 by f0dder
I always use following technic about module handle:


; in non initialized variables
hInstance dd ?


; In the begining of the program.
invoke GetModulHandle, 0
mov [hInstance], eax


And I though, whether it is appropriate to use this technic for GetProcessHeap as well.

Regards
Posted on 2004-03-14 06:26:20 by JohnFound
Hi f0dder,

Actually I had expected this response from you :)
Posted on 2004-03-14 09:08:07 by roticv
I agree with f0dder here. There is a time for short cuts, but this one has no advantage, only risk.

:NaN:
Posted on 2004-03-14 10:12:36 by NaN
Agreed!
Posted on 2004-03-14 10:21:04 by SubEvil

And I though, whether it is appropriate to use this technic for GetProcessHeap as well.

This is a good question John, and more useful than shaving a few cycles off your program startup. (Iirc GetProcessHeap just fetches the variable with a lookup through the TIB). But even though it's not a big speed overhead, it's annoying to do the GetProcessHeap call all the time.

I would assume it's safe to store the process heap handle in a variable. (Afaik) the process heap is always created (PE header flags), and since we're dealing with HANDLEs, there's no reason why the handle value vould change (afaik you cannot destroy the default process heap). So unless anybody knows better, I'd say it's safe to use GetProcessHeap once.


Actually I had expected this response from you :)

And it's not without reason. Programmers doing this kind of code in release applications should be shot through their kneecaps, and possibly have their fingers cut off as well. It's annoying to have to fix other people's bugs to be able to run their stuff.
Posted on 2004-03-14 10:36:45 by f0dder
Programmers doing this kind of code in release applications should be shot through their kneecaps, and possibly have their fingers cut off as well.


I have never used a hard coded instance handle but I think that's a little severe :grin:

Another interesting one would be the default handle returned from SelectObject, it would be convenient not to have to save the old handle every time when creating a DC for a back buffer. For example is it always 0185000Fh for bitmaps ?
Posted on 2004-03-14 10:46:06 by donkey
Originally posted by f0dder

This is a good question John, and more useful than shaving a few cycles off your program startup. (Iirc GetProcessHeap just fetches the variable with a lookup through the TIB). But even though it's not a big speed overhead, it's annoying to do the GetProcessHeap call all the time.


If you make thousends of dynamic allocations/deallocations on complex data structures, avoiding one call may give valuable speed gain, IMHO. On other hand this may save a lot of register savings and to increase readability of the source.
I write very often similar to below constructions:


push ecx
invoke GetProcessHeap
invoke HeapAlloc, eax, 0 ; size from the stack.


While the following is smaller, simple and more readable:


invoke HeapAlloc, [ProcessHeap], 0, ecx


I will definately try this technique in my sources.

Regards.
Posted on 2004-03-14 16:08:05 by JohnFound

I have never used a hard coded instance handle but I think that's a little severe :grin:

Yeah, it's a little severe - but look at the win32 version of XCOM "oh, why use pitch, width and pitch are always the same on OUR boxes". This was easy to fix for me, though. Look at the win32 POD... "Oh, port I/O works fine on our windows version, so let's do port I/O" - I'm considering having a look at fixing this, too. Instance handle stuff isn't that severe, and would probably be emulated in the future if the OS changes that much, but it's the same mentality.

As for SelectObject, sure, it would be handy not having to save those pesky values. Still doesn't feel too safe to hardcode those values, though... besides, your code is more generic if you save the old value :)


If you make thousends of dynamic allocations/deallocations on complex data structures, avoiding one call may give valuable speed gain, IMHO.

Probably, yes... and if memory allocation is your bottleneck, it might also pay off to fiddle around with implementing alternative allocation schemes (ontop of HeapAlloc or VirtualAlloc, things like pooled alloc/dealloc etc).


I will definately try this technique in my sources.

I wish I knew if it's "officially safe" to do this... It 'feels' safe though, and I'm doing it myself.
Posted on 2004-03-14 17:59:16 by f0dder