Discussion:
Windows GUI application , with console?
(too old to reply)
T***@gmail.com
2005-11-11 09:03:40 UTC
Permalink
Hey,

I'm on Windows XP and use .NET 2003. I would like to create a wxWidgets
application that also has a console. So I can output (using printf).

I tried the following code:

//=================================================
#include <wx/wx.h>

class Application : public wxApp
{
public:
virtual bool OnInit(void);

};

IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"My Window",wxPoint(30,30));
testframe->Show();

printf("Does this work?");

return true;
}

int main( int argc, char** argv )
{
wxEntry(argc,argv);

return 0;
}

//=================================================


This code crashes upon creation of the wxFrame. Is there something I'm
doing wrong? Is this even possible? How? :-)


Thanks,
Timothy
John Ratliff
2005-11-11 09:18:49 UTC
Permalink
Post by T***@gmail.com
Hey,
I'm on Windows XP and use .NET 2003. I would like to create a wxWidgets
application that also has a console. So I can output (using printf).
//=================================================
#include <wx/wx.h>
class Application : public wxApp
{
virtual bool OnInit(void);
};
IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"My Window",wxPoint(30,30));
testframe->Show();
printf("Does this work?");
return true;
}
int main( int argc, char** argv )
{
wxEntry(argc,argv);
return 0;
}
//=================================================
This code crashes upon creation of the wxFrame. Is there something I'm
doing wrong? Is this even possible? How? :-)
Thanks,
Timothy
From the docs, wxEntry(argc, argv) is for platform dependent
initialization on Unix. So that seems doomed to fail.

I'm fairly certain Windows apps (GUI apps anyway using Win32) require a
WinMain.

Do you need IMPLEMENT_APP_NO_MAIN()? Why not use IMPLEMENT_APP and let
wx create your main()?

There's nothing wrong with printf(). I've used it before, though you may
have to call fflush(stdout) after you call it to make sure you actually
get the output, otherwise it may not flush till the app closes and you
may or may not see the output at that point.

Windows apps don't generally open a console either, so there may or may
not be a problem there. I don't use VC.NET, I use mingw/msys and run
from msys when testing, but you may have to open a console; I'm not sure
at this point.

--John Ratliff
T***@gmail.com
2005-11-11 11:01:10 UTC
Permalink
I have some code that now actually runs and creates both a console and
a wxApp+wxFrame.

A problem arrises when I close the console window, the application
closes but doesn't properly clean up wxApp, (if you take a look at the
code you'll notice my comment)


//=================================================
#include <wx/wx.h>
#include <stdio.h>

class Application : public wxApp
{
public:
virtual bool OnInit(void);
};

IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"wxFrame",wxPoint(30,30));
testframe->Show();

for (int i = 0; i < 100; i++) {
printf("wheeeeeeeeeeeee\n"); // these actually appear in the console
now
}

return true;
}

int main(int ac,char *av[])
{
HINSTANCE inst;
inst=(HINSTANCE)GetModuleHandle(NULL);

// use the wxEntry method as defined in wx/msw/app.h, I've included
this decleration as a comment below
wxEntry(inst);

/*
wxEntry(HINSTANCE hInstance,
HINSTANCE hPrevInstance = NULL,
wxCmdLineArgType pCmdLine = NULL,
int nCmdShow = SW_SHOWNORMAL);
*/

// this return is never reached when closing the console,
// only when closing the wxFrame, hence the wxApp
return 0;
}
//=================================================
John Ratliff
2005-11-11 12:01:20 UTC
Permalink
Post by T***@gmail.com
I have some code that now actually runs and creates both a console and
a wxApp+wxFrame.
A problem arrises when I close the console window, the application
closes but doesn't properly clean up wxApp, (if you take a look at the
code you'll notice my comment)
I still think you should let wx define your main, but I don't think it's
a problem here.

Well, I can't seem to compile the app with VC++ 8. I don't know what I'm
doing wrong, but I get unresolved linker errors that don't make sense to
me as they should be part of the monolithic wx library I compiled.

But leaving that aside, when I compiled from msys, I get an application
that opens a frame, but does not open a console. I get no printing
whatsoever, and the app doesn't close until the frame is closed. The app
shouldn't close until the frame is closed anyway, so I'm not quite sure
what your problem is.

If the app doesn't open a console, then closing a different console
would have no effect on the application. I'm not really sure closing the
console would necessarily close the application if you had to open one
specifically, but I'm not 100% sure about this.

So, when you close the console you opened your app from, what happens?
Does the frame stay there, or does it go away? If it goes away, then how
do you know the app doesn't exit?

--John Ratliff
T***@gmail.com
2005-11-11 12:27:37 UTC
Permalink
Post by John Ratliff
I still think you should let wx define your main, but I don't think it's
a problem here.
I also have some code that does this, and I use some win32 calls to
actually create a console:

==================================
AllocConsole();
SetConsoleTitle("Debugging Output");
GetConsoleTitle(title, 256);

hCrt = _open_osfhandle((long) GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
hf = _fdopen( hCrt, "w" );
*stdout = *hf;
hCrt = _open_osfhandle((long) GetStdHandle(STD_ERROR_HANDLE),_O_TEXT);
hf = _fdopen( hCrt, "w" );
*stderr = *hf;
i = setvbuf( stderr, NULL, _IONBF, 0 );
hCrt = _open_osfhandle((long) GetStdHandle(STD_INPUT_HANDLE), _O_TEXT
);
hf = _fdopen( hCrt, "r" );
*stdin = *hf;
i = setvbuf( stdin, NULL, _IONBF, 0 );
================================================

This leads to exactly the same behaviour as with the code I pasted
earlier though. This makes sense because I actually the the same thing
as wxWidgets would have done with the IMPLEMENT_APP or
IMPLEMENT_APP_CONSOLE macros.
Post by John Ratliff
Well, I can't seem to compile the app with VC++ 8. I don't know what I'm
doing wrong, but I get unresolved linker errors that don't make sense to
me as they should be part of the monolithic wx library I compiled
Did you follow the instructions to create a wxwidgets .NET project? It
requires some extra input, optimisation needs to be turned of etc.
(explained better in the wiki)
Post by John Ratliff
So, when you close the console you opened your app from, what happens?
Does the frame stay there, or does it go away? If it goes away, then how
do you know the app doesn't exit?
When I close the console the application exists straight away, so it
never reaches anything in the wxApp / wxFrame. This results in .NET
2003 complaining about memory leaks etc, since wxApp and wxFrame aren't
deleted properly. When I close the wxFrame however the wxApp closes and
it enters the main() function again.
I'm not very familiar with win32, but I suspect that the close of the
console somehow generates an event that is handled by a different event
loop?

Timothy
John Ratliff
2005-11-11 15:57:18 UTC
Permalink
Post by T***@gmail.com
Post by John Ratliff
I still think you should let wx define your main, but I don't think it's
a problem here.
I also have some code that does this, and I use some win32 calls to
==================================
AllocConsole();
SetConsoleTitle("Debugging Output");
GetConsoleTitle(title, 256);
hCrt = _open_osfhandle((long) GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
hf = _fdopen( hCrt, "w" );
*stdout = *hf;
hCrt = _open_osfhandle((long) GetStdHandle(STD_ERROR_HANDLE),_O_TEXT);
hf = _fdopen( hCrt, "w" );
*stderr = *hf;
i = setvbuf( stderr, NULL, _IONBF, 0 );
hCrt = _open_osfhandle((long) GetStdHandle(STD_INPUT_HANDLE), _O_TEXT
);
hf = _fdopen( hCrt, "r" );
*stdin = *hf;
i = setvbuf( stdin, NULL, _IONBF, 0 );
================================================
Looks like a lot of code. I've done this in one of my apps:

#ifdef _WIN32
AllocConsole();
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
#endif

Looks a bit easier than what you did, but I don't know what setvbuf does.
Post by T***@gmail.com
This leads to exactly the same behaviour as with the code I pasted
earlier though. This makes sense because I actually the the same thing
as wxWidgets would have done with the IMPLEMENT_APP or
IMPLEMENT_APP_CONSOLE macros.
Post by John Ratliff
Well, I can't seem to compile the app with VC++ 8. I don't know what I'm
doing wrong, but I get unresolved linker errors that don't make sense to
me as they should be part of the monolithic wx library I compiled
Did you follow the instructions to create a wxwidgets .NET project? It
requires some extra input, optimisation needs to be turned of etc.
(explained better in the wiki)
I don't know why optimization would affect linking. Besides, the wiki
says this was fixed with VC 7.1, and I'm using 8.

But yes, I followed the wiki.
Post by T***@gmail.com
Post by John Ratliff
So, when you close the console you opened your app from, what happens?
Does the frame stay there, or does it go away? If it goes away, then how
do you know the app doesn't exit?
When I close the console the application exists straight away, so it
never reaches anything in the wxApp / wxFrame. This results in .NET
2003 complaining about memory leaks etc, since wxApp and wxFrame aren't
deleted properly. When I close the wxFrame however the wxApp closes and
it enters the main() function again.
This is getting very confusing. Let's start again. I want to know what
happens when you do the following:

a) compile the application
b) start a console
c) run the application from the console
d) close the console (use the new console window's close button, NOT the
close button on the frame)

What happens to the frame? Is it still there or does it go away?

If the app exits, there is no memory leak. An application can't close
and have a memory leak. Memory is reabsorbed by the system when the
process ends.
Post by T***@gmail.com
I'm not very familiar with win32, but I suspect that the close of the
console somehow generates an event that is handled by a different event
loop?
It is possible there is some signal send to child processes of the
console, but I don't know exactly how Windows works in this regard. I
don't think there is any specific event generated, but I don't know that
for sure.

--John Ratliff
John Ratliff
2005-11-11 16:53:08 UTC
Permalink
Post by T***@gmail.com
Post by John Ratliff
So, when you close the console you opened your app from, what happens?
Does the frame stay there, or does it go away? If it goes away, then how
do you know the app doesn't exit?
When I close the console the application exists straight away, so it
never reaches anything in the wxApp / wxFrame. This results in .NET
2003 complaining about memory leaks etc, since wxApp and wxFrame aren't
deleted properly. When I close the wxFrame however the wxApp closes and
it enters the main() function again.
I'm not very familiar with win32, but I suspect that the close of the
console somehow generates an event that is handled by a different event
loop?
Okay, I got VC++8 to link finally. I needed to use the MT C library DLL
runtime. Whatever. God I hate Microsoft and all their stupid programs.

Anyway, when I compile your app, I get a console with a bunch of
"wheeeee" (presumably 100). If I close it, the app closes. No problems
whatsoever. If I close the frame, the app closes. Doesn't seem to be any
problem on my end, so I'm not quite sure what you're referring to. I
have no mem leak, and I have no issues with closing.

--John Ratliff
T***@gmail.com
2005-11-14 08:50:00 UTC
Permalink
Post by John Ratliff
Okay, I got VC++8 to link finally. I needed to use the MT C library DLL
runtime. Whatever. God I hate Microsoft and all their stupid programs.
Anyway, when I compile your app, I get a console with a bunch of
"wheeeee" (presumably 100). If I close it, the app closes. No problems
whatsoever. If I close the frame, the app closes. Doesn't seem to be any
problem on my end, so I'm not quite sure what you're referring to. I
have no mem leak, and I have no issues with closing.
Sorry I wasn't able to reply this weekend.

The problem with me occures when I close the console window as opened
by the program, it never properly destoys the wxApp and wxFrame
objects. Of course this doesn't lead to a memory leak, but the Visual
Studio debugger does report the memory that is not freed properly. This
also means that it will not call any deconstructor on application exit
(when closing trough the console window), which could potentially be a
problem.

The confusion may have been because I refer to the console window as
opened by the program. Either by the commands I've used to explicitly
open the console window, or by setting the /subsysten:console linker
option. I think you may also refer to the console as opened perhaps by
"Start->Run->cmd"?

Closing the wxFrame is fine, it simply closes and then the wxApp closes
which exists the application. Closing the console window however also
exits the application but it then never reaches the wxApp class and
it's deconstructor.
T***@gmail.com
2005-11-14 09:00:39 UTC
Permalink
p.s.

This is the simplified code:
This should work with a default wxWidgets project (/SUBSYSTEM:windows).
It (at least on my system) does show the problem when closing the
console window the application exists but doesn't properly destroy the
wxFrame and wxApp objects.

//================================================
#include <wx/wx.h>
#include <stdio.h>

class Application : public wxApp
{
public:
virtual bool OnInit(void);
virtual int OnExit(void);
};

IMPLEMENT_APP(Application)
bool Application::OnInit()
{
wxFrame *testframe;

AllocConsole();
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

testframe = new wxFrame(NULL,wxID_ANY,"wxFrame",wxPoint(30,30));
testframe->Show();

for (int i = 0; i < 10; i++) {
printf("wheeeeeeeeeeeee\n");
}

return true;
}

int Application::OnExit()
{
printf("It never reaches this when closing the console, only when
closing the wxFrame");
return 0;
}

//================================================
Marco Cavallini [KOAN]
2005-11-11 09:24:22 UTC
Permalink
Post by T***@gmail.com
I'm on Windows XP and use .NET 2003. I would like to create a wxWidgets
application that also has a console. So I can output (using printf).
//=================================================
#include <wx/wx.h>
class Application : public wxApp
{
virtual bool OnInit(void);
};
IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"My Window",wxPoint(30,30));
testframe->Show();
printf("Does this work?");
return true;
}
int main( int argc, char** argv )
{
wxEntry(argc,argv);
return 0;
}
//=================================================
This code crashes upon creation of the wxFrame. Is there something I'm
doing wrong? Is this even possible? How? :-)
You have to move the frame * declaration in a place that persist when you
exit from OnInit.
Maybe try placing it into the class.

class Application : public wxApp
{
public:
virtual bool OnInit(void);

wxFrame *testframe;
};

Marco Cavallini
Koan s.a.s. - Bergamo - ITALIA
Embedded and Real-Time Software Engineering
www.koansoftware.com | www.klinux.org


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-***@lists.wxwidgets.org
For additional commands, e-mail: wx-users-***@lists.wxwidgets.org
John Ratliff
2005-11-11 10:13:52 UTC
Permalink
Post by Marco Cavallini [KOAN]
Post by T***@gmail.com
I'm on Windows XP and use .NET 2003. I would like to create a wxWidgets
application that also has a console. So I can output (using printf).
//=================================================
#include <wx/wx.h>
class Application : public wxApp
{
virtual bool OnInit(void);
};
IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"My Window",wxPoint(30,30));
testframe->Show();
printf("Does this work?");
return true;
}
int main( int argc, char** argv )
{
wxEntry(argc,argv);
return 0;
}
//=================================================
This code crashes upon creation of the wxFrame. Is there something I'm
doing wrong? Is this even possible? How? :-)
You have to move the frame * declaration in a place that persist when
you exit from OnInit.
Maybe try placing it into the class.
class Application : public wxApp
{
virtual bool OnInit(void);
wxFrame *testframe;
};
That makes no sense. Where the declaration is placed is meaningless.

--John Ratliff
Spacen Jasset
2005-11-11 11:51:23 UTC
Permalink
This post might be inappropriate. Click to display it.
T***@gmail.com
2005-11-11 12:36:02 UTC
Permalink
This post might be inappropriate. Click to display it.
chris elliott
2005-11-11 12:53:11 UTC
Permalink
Post by Spacen Jasset
Why not use a wxWidgets control instead of a console?
look for wxMessageOutput in include/wx/msgout.h

chris

---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-***@lists.wxwidgets.org
For additional commands, e-mail: wx-users-***@lists.wxwidgets.org
Ryan Norton
2005-11-11 18:07:33 UTC
Permalink
Post by John Ratliff
Okay, I got VC++8 to link finally. I needed to use the MT C library DLL
runtime. Whatever. God I hate Microsoft and all their stupid programs.
Okay, I got GCC 3 to link finally. I needed to make sure the libraries were
in "the right order" for the linker. Whatever. God I hate the Free Software
Foundation and all their stupid programs.

Ryan


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-***@lists.wxwidgets.org
For additional commands, e-mail: wx-users-***@lists.wxwidgets.org
John Ratliff
2005-11-12 03:18:30 UTC
Permalink
Post by Ryan Norton
Post by John Ratliff
Okay, I got VC++8 to link finally. I needed to use the MT C library DLL
runtime. Whatever. God I hate Microsoft and all their stupid programs.
Okay, I got GCC 3 to link finally. I needed to make sure the libraries
were in "the right order" for the linker. Whatever. God I hate the Free
Software Foundation and all their stupid programs.
:-)

--John Ratliff
Ryan Norton
2005-11-11 19:03:38 UTC
Permalink
Post by T***@gmail.com
I'm not very familiar with win32, but I suspect that the close of the
console somehow generates an event that is handled by a different event
loop?
That shouldn't be a problem though. You could try calling FreeConsole before
you exit.

I know at least on Win95 it's possible to get the window handle of the
console via FindWindow and you might be able to do the same searching for
GetConsoleTitle through it, not sure there though. Then make a wxWindow out
of it and trace the events, although I seriously doubt that's what is
happening.
Post by T***@gmail.com
but I don't know what setvbuf does.
Pretty sure he/she wants to turn of handle buffering. setbuf(stdin, NULL)
would have been easier though :).

You can do some pretty neat things with the Win32 console too - like make it
full screen etc.

http://msdn.microsoft.com/library/en-us/dllproc/base/console_reference.asp

I.E.

TCHAR GetUnshownCharFromConsole()
{
HANDLE hStdin;
DWORD cNumRead, fdwMode, fdwSaveOldMode, i;
INPUT_RECORD irInBuf[ 128 ];

// Get the standard input handle.

hStdin = GetStdHandle(STD_INPUT_HANDLE);

// Save the current input mode, to be restored on exit.

GetConsoleMode(hStdin,
& fdwSaveOldMode);

// Enable the window and mouse input events.

fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT;
SetConsoleMode(hStdin,
fdwMode);

// Loop to read and handle the input events.

while (1)
{
// Wait for the events.

ReadConsoleInput(hStdin, // input buffer handle
irInBuf, // buffer to read into
128, // size of read buffer
& cNumRead); // number of records read


// Dispatch the events to the appropriate handler.

for (i = 0; i < cNumRead; i++)
{
switch (irInBuf[ i ].EventType)
{
case KEY_EVENT:
// keyboard input
if (irInBuf[ i ].Event.KeyEvent.bKeyDown == TRUE)
{
return irInBuf[ i ].Event.KeyEvent.uChar.AsciiChar;
}
break;
}
}
}
}


Ryan


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-***@lists.wxwidgets.org
For additional commands, e-mail: wx-users-***@lists.wxwidgets.org
Roger Soif
2005-11-13 08:58:34 UTC
Permalink
Here is my code that works fine for creating a console

bool MyApp::OnInit(){
#ifdef WIN32
AllocConsole();
long hStdOut = (long) GetStdHandle(STD_OUTPUT_HANDLE);
int hConHandle = _open_osfhandle(hStdOut, _O_TEXT);
FILE *fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
ios::sync_with_stdio();
#endif

HTH
Post by T***@gmail.com
Hey,
I'm on Windows XP and use .NET 2003. I would like to create a wxWidgets
application that also has a console. So I can output (using printf).
//=================================================
#include <wx/wx.h>
class Application : public wxApp
{
virtual bool OnInit(void);
};
IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"My Window",wxPoint(30,30));
testframe->Show();
printf("Does this work?");
return true;
}
int main( int argc, char** argv )
{
wxEntry(argc,argv);
return 0;
}
//=================================================
This code crashes upon creation of the wxFrame. Is there something I'm
doing wrong? Is this even possible? How? :-)
Thanks,
Timothy
Roger Soif
2005-11-13 09:01:09 UTC
Permalink
I forgot includes

#ifdef WIN32
#include <windows.h>
#include <io.h>
#endif
Post by Roger Soif
Here is my code that works fine for creating a console
bool MyApp::OnInit(){
#ifdef WIN32
AllocConsole();
long hStdOut = (long) GetStdHandle(STD_OUTPUT_HANDLE);
int hConHandle = _open_osfhandle(hStdOut, _O_TEXT);
FILE *fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
ios::sync_with_stdio();
#endif
HTH
Post by T***@gmail.com
Hey,
I'm on Windows XP and use .NET 2003. I would like to create a wxWidgets
application that also has a console. So I can output (using printf).
//=================================================
#include <wx/wx.h>
class Application : public wxApp
{
virtual bool OnInit(void);
};
IMPLEMENT_APP_NO_MAIN(Application)
bool Application::OnInit()
{
wxFrame *testframe;
testframe = new wxFrame(NULL,wxID_ANY,"My Window",wxPoint(30,30));
testframe->Show();
printf("Does this work?");
return true;
}
int main( int argc, char** argv )
{
wxEntry(argc,argv);
return 0;
}
//=================================================
This code crashes upon creation of the wxFrame. Is there something I'm
doing wrong? Is this even possible? How? :-)
Thanks,
Timothy
Ryan Norton
2005-11-14 15:37:28 UTC
Permalink
http://sourceforge.net/tracker/index.php?func=detail&aid=1356623&group_id=9863&atid=309863

[[Ryan]]


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-***@lists.wxwidgets.org
For additional commands, e-mail: wx-users-***@lists.wxwidgets.org
T***@gmail.com
2005-11-14 16:24:01 UTC
Permalink
Ah nice to see that there is a possible solution and that it seems not
to be my fault! :-)

I've applied the patch to the wxWidgets I use (2.6.1) (note I applied
it manually). It does reach the OnExit routine now and all the memory
is properly cleaned before the application exists, which is nice! The
delay however still causes some problems. When closing the console, a
windows pop up with an error message: "Windows cannot end this program.
It may need more time to complete an operation". I noticed your comment
about this in the patch, so I'll just keep an eye on the tracker.
Oh and I guess I better try this patch out on the cvs version as well.

In any case, thank you for diving into this!

Timothy
Ryan Norton
2005-11-16 01:49:37 UTC
Permalink
Post by T***@gmail.com
"Windows cannot end this program.
It may need more time to complete an operation". I noticed your comment
about this in the patch, so I'll just keep an eye on the tracker.
Oh and I guess I better try this patch out on the cvs version as well.
The problem is that if windows exits the console it wants the app to exit
IMMEDIATELY. Unfortunately I don't know of any way to "hard shutdown" wx
that doesn't result in memory leaks....

Ryan


---------------------------------------------------------------------
To unsubscribe, e-mail: wx-users-***@lists.wxwidgets.org
For additional commands, e-mail: wx-users-***@lists.wxwidgets.org
Loading...