Click to See Complete Forum and Search --> : cannot create a window


Pisto
September 30th, 2008, 03:36 PM
Hi!
I'm testing in a stand alone executable some C code that I'll use in a dll. The code creates a window only for receiving messages. The problem is that CreateWindow returns 0 and GetLastError too, so I can't get the cause.
This is the code:

int APIENTRY WinMain(HINSTANCE mio,HINSTANCE cheserve,LPSTR cmd,int finestra){
HWND window;
WNDCLASSA wnd;
ZeroMemory(wnd,sizeof(wnd));
wnd.hInstance=mio;
wnd.lpfnWndProc=JoinMessageHandler;
wnd.lpszClassName="JoinWindow";
if(RegisterClass(&wnd)==0)
printf("errore1");
window=CreateWindow("JoinWindow",NULL,0,0,0,0,0,HWND_MESSAGE,NULL,mio,NULL);
if(window==NULL)
printf("%X",GetLastError());
return 0;
}

(it prints 0)

I read somewhere that the executable needs to be marked someway as a GUI program, but I think it's already been done by my compiler (mingw, and I use eclipse cdt as IDE), because I opened the executable with IDA and the first instruction is a call to __set_app_type(1).

JohnCz
September 30th, 2008, 08:35 PM
I do not see any reason for returning NULL handle.
Your WinMain is missing message loop, besides, right after creation, your window will stop in GetMessage call since window does not receive any messages (or you did not show source of those messages.

Please post test app for us to see what could go wrong. Your code snippet may be incomplete.

Pisto
October 1st, 2008, 08:47 AM
This code is just for testing my first code with windows, and so far I'm stuck with that null pointer, the rest later. Anyway, I'll use windows just for WSAAsynchSelect() and to communicate with another process (that will get it through FindWindowEx), so I don't think I need a loop in the first case, but yes for the second (correct me if I'm wrong).

The code posted lacks of an empty implementation of JoinMessageHandler, needed just to fool the compiler.



Should I try with Visual C++? Or is it useless, it can't be a problem of the compiler?

Notsosuperhero
October 1st, 2008, 09:07 AM
If you have no loop in there, the program will exit.

Pisto
October 1st, 2008, 12:59 PM
I don't care! I just want to know why CreateWindow returns 0!

JohnCz
October 1st, 2008, 02:48 PM
POst your project here.

Pisto
October 1st, 2008, 04:50 PM
ok, this is the complete code of the test project:#include <stdio.h>

#define _WIN32_WINNT 0x0501
#include <windows.h>

LRESULT CALLBACK JoinMessageHandler(HWND wind,UINT message,WPARAM a,LPARAM b){
return 0;
}

int APIENTRY WinMain(HINSTANCE mio,HINSTANCE cheserve,LPSTR cmd,int finestra){
HWND window;
WNDCLASSA wnd;
ZeroMemory(&wnd,sizeof(wnd));
wnd.hInstance=mio;
wnd.lpfnWndProc=JoinMessageHandler;
wnd.lpszClassName="JoinWindow";
if(RegisterClass(&wnd)==0)
printf("errore1");
window=CreateWindow("JoinWindow",NULL,0,0,0,0,0,HWND_MESSAGE,NULL,mio,NULL);
if(window==NULL)
printf("%X",GetLastError());
return 0;
}

it prints 0.

this is the compiling log of eclipse:

**** Build of configuration Release for project roba ****

**** Internal Builder is used for build ****
gcc -O3 -Wall -c -fmessage-length=0 -oTest.o ..\Test.c
..\Test.c: In function `WinMain':
..\Test.c:21: warning: unsigned int format, DWORD arg (arg 2)
gcc -oroba.exe Test.o
Build complete for project roba
Time consumed: 1844 ms.


the real code will be in a DllMain.


EDIT:
changing the callback function this way:LRESULT CALLBACK JoinMessageHandler(HWND wind,UINT message,WPARAM a,LPARAM b){
return DefWindowProc(wind,message,a,b);
}fixes it. can anyone explain it to me?

kirants
October 1st, 2008, 06:29 PM
The result of a window proc has meaning and hence you cannot simply return 0. The return value has significance for each specific message and so it has to be considered. Returning DefWindowProc means you are asking windows to do what is necessary and DefWindowProc is returning the correct thing.

Notsosuperhero
October 1st, 2008, 07:17 PM
The windows procedure is there to handle all the messages windows is sending to your application window. Simply not handling any of them will result in your application doing absolutely nothing.

DefWindowProc simply inserts Windows' default handling of the messages so you don't have to, and to make sure that all the messages are handled.

JohnCz
October 7th, 2008, 11:56 PM
Notsosuperhero is absolutely 100% right. It is very important what is a return code from a window procedure.
Values are different for each message.
Before CreateWindow return, window receives several messages.
The first message window receives is WM_GETMINMAXINFO. Hadler should return 0 but it is irrelevant.
Next message is WM_NCCREATE. If oyu return 0, creation of the window is aborted and null handle is returned as a result. Handler should return 1 (or non-zero).
Next: WM_NCCALCSIZE handler should return 0 but any other value will do for a message only window.
Last message is WM_CREATE. If -1 is returned the resulr will be null handle.
As you can see you have to handle messages properly,
If you want to process messages you must include message loop, otherwise window will be destroyed right after creation.

Pisto
October 8th, 2008, 03:10 PM
ok so: I need to provide a thread (that owns the window?) to use the message design, am I right?

I hoped, when reading the msdn about this feature, that the window procedure was executed by a system-provided thread, like in java's swing, because the job that I have to do in it is small and guaranteed to not block.

JohnCz
October 8th, 2008, 07:17 PM
I do not quite understand. When you start Windows application, it is being executed in one main excursion thread. You can create as many worker or GUI threads as you need. In your case, you are creating main window of this application that is by your design a message only window. I do not know what it has to do with Java swinging or not :D .

Window is not owned by any thread; it can be owned by other windows but it is rare for main window. Window message loop is running in the single thread of execution.

Perhaps it would be easier for both of us if you give exact description of what you are trying to accomplish.

Pisto
October 9th, 2008, 08:54 AM
the swing example meant this: you add listener to button, menus etc you know? ok, the listener implementation is executed by a thread that's created by the swing library itself, and if you use this thread for long computations, the GUI will be gstuck until you return from the listener method. I hoped that comething like this was done for windows (listener=window procedure, swing thread=some thread that you don't have to create, a button action=some message code with its 2 parameters), but if I understand correctly you need a thread that throught DispatchMessage explicitly and manually calls the window procedure.

ok, this is the complete project.
I'm writing a dll (http://worms2d.info/RubberWorm) that is injected in a program with a loader. In the DllMain, I do some initialization (code hooking), and I need to create one or more message-only windows for: some networking (WSAAsyncSelect), and inter-process communication (it needs to communicate with a separate and independent VB program, not coded by me, that's needed principally as a GUI).

I guess it must work if in the initialization code (DllMain) I create a thread whose only job is the canonical message loop. If that's still wrong, I'm going to lose a lot of self-esteem.

JohnCz
October 9th, 2008, 06:23 PM
Check this article (http://www.codeguru.com/cpp/frameworks/advancedui/windowingtechniquesandclasses/print.php/c12689__3/), it may help you.
You can find more on this site.