Google Groups Home
Help | Sign in
Hybrid GUI/Console App
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  13 messages - Collapse all
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
crjjrc  
View profile
 More options Apr 11, 11:28 am
Newsgroups: comp.soft-sys.wxwindows
From: crjjrc <crj...@gmail.com>
Date: Fri, 11 Apr 2008 08:28:22 -0700 (PDT)
Local: Fri, Apr 11 2008 11:28 am
Subject: Hybrid GUI/Console App
I think I've got a solution for making a hybrid application that can
either be run in GUI or console mode, depending on command-line
parameters.  However, I've been unable to find an example of such a
program using wxWidgets.  wx-users contains much discussion about
this, but I'm failing to find any code.

My solutions follows.  If any command-line parameter is passed, no GUI
is used.  (The check is a bit of a hack on MSW, I know.)  Any thing
I'm doing wrong?

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

class GUITest : public wxApp {
   bool OnInit();

};

bool GUITest::OnInit() {
   wxFrame *frame = new wxFrame(NULL, -1, _T("Test"),
wxDefaultPosition,
                                wxDefaultSize);
   frame->Show();
   SetTopWindow(frame);
   return true;

}

class GUIlessTest : public wxAppConsole {
   bool OnInit();

};

bool GUIlessTest::OnInit() {
   std::cout << "guiless" << std::endl;
   return false;

}

#ifdef __WXMSW__
extern "C" int WINAPI WinMain(HINSTANCE hInstance,
                              HINSTANCE hPrevInstance,
                              wxCmdLineArgType lpCmdLine,
                              int nCmdShow) {
   int argc = 2 * lpCmdLine;
#else
int main(int argc, char **argv) {
#endif
   if (argc == 2) {
      GUIlessTest *app = new GUIlessTest;
   } else {
      GUITest *app = new GUITest;
   }
#ifdef __WXMSW__
   return wxEntry(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
#else
   return wxEntry(argc, argv);
#endif


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vadim Zeitlin  
View profile
 More options Apr 11, 10:36 pm
Newsgroups: comp.soft-sys.wxwindows
From: Vadim Zeitlin <va...@wxwidgets.org>
Date: Sat, 12 Apr 2008 04:36:54 +0200
Local: Fri, Apr 11 2008 10:36 pm
Subject: Re: Hybrid GUI/Console App
On Fri, 11 Apr 2008 08:28:22 -0700 (PDT) crjjrc <crj...@gmail.com> wrote:

c> My solutions follows.  If any command-line parameter is passed, no GUI
c> is used.  (The check is a bit of a hack on MSW, I know.)  Any thing
c> I'm doing wrong?

 I don't think you do anything wrong but it would be nicer (e.g. if you
intend to put this on the wiki or maybe submit for inclusion in the manual
or as a new sample) if wx command line parsing could be used, is it too
late to do this in OnCmdLineParsed()?

 Also, writing GUIlessTest seems rather pointless, usually people want to
have their "main()" called if they don't use GUI so you could just replace
this class creation with calls to wxInitialize (or use wxInitializer) and
call some console_main() function.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
crjjrc  
View profile
 More options Apr 14, 10:04 am
Newsgroups: comp.soft-sys.wxwindows
From: crjjrc <crj...@gmail.com>
Date: Mon, 14 Apr 2008 07:04:30 -0700 (PDT)
Local: Mon, Apr 14 2008 10:04 am
Subject: Re: Hybrid GUI/Console App
On Apr 11, 9:36 pm, Vadim Zeitlin <va...@wxwidgets.org> wrote:

> On Fri, 11 Apr 2008 08:28:22 -0700 (PDT) crjjrc <crj...@gmail.com> wrote:

> c> My solutions follows.  If any command-line parameter is passed, no GUI
> c> is used.  (The check is a bit of a hack on MSW, I know.)  Any thing
> c> I'm doing wrong?

>  I don't think you do anything wrong but it would be nicer (e.g. if you
> intend to put this on the wiki or maybe submit for inclusion in the manual
> or as a new sample) if wx command line parsing could be used, is it too
> late to do this in OnCmdLineParsed()?

Considering that OnCmdLineParsed() is a member of wxAppConsole, I
don't think this could be done since we are using the command-line
arguments to figure which application to create.  Or am I missing
something?

Alternately I can just trigger the parsing myself by instancing a
wxCmdLineParser in main() or WinMain() and calling Parse(), right?
I'm not sure how to get the appropriate argc and argv for the parser's
constructor though.  On Windows, I get one string in lpCmdLine, which
doesn't include the program name.  Does wxCmdLineParser::SetCmdLine()
expect the program name to be first?  It doesn't say in the docs.
Everywhere else, the incoming argv is char ** and the constructor
expects wxChar **.  Is there an easy way to convert this?  wxApp*
objects set their own argc and argv somewhere behind the scenes, and
I'm not sure how they do it.

- Chris


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vadim Zeitlin  
View profile
 More options Apr 14, 3:53 pm
Newsgroups: comp.soft-sys.wxwindows
From: Vadim Zeitlin <va...@wxwidgets.org>
Date: Mon, 14 Apr 2008 21:53:42 +0200
Local: Mon, Apr 14 2008 3:53 pm
Subject: Re[2]: Hybrid GUI/Console App
On Mon, 14 Apr 2008 07:04:30 -0700 (PDT) crjjrc <crj...@gmail.com> wrote:

c> Considering that OnCmdLineParsed() is a member of wxAppConsole, I
c> don't think this could be done since we are using the command-line
c> arguments to figure which application to create.  Or am I missing
c> something?

 I thought about deriving a wxGUIOrConsoleApp class from wxApp (i.e. the
GUI version) but overriding its virtual Initialize() to call wxAppConsole
version if argc != 1. I didn't test it but I think it should be possible to
make this work.

c> Alternately I can just trigger the parsing myself by instancing a
c> wxCmdLineParser in main() or WinMain() and calling Parse(), right?

 With a "smart" wxApp class above you wouldn't need to manually deal with
WinMain() at all.

c> I'm not sure how to get the appropriate argc and argv for the parser's
c> constructor though.  On Windows, I get one string in lpCmdLine

 You can use wxCmdLineParser::ConvertStringToArgs() just as the code in
src/msw/main.cpp does. But, again, hopefully this is unnecessary anyhow.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
w...@61131.com  
View profile
 More options Apr 14, 4:05 pm
Newsgroups: comp.soft-sys.wxwindows
From: <w...@61131.com>
Date: Mon, 14 Apr 2008 22:05:07 +0200
Local: Mon, Apr 14 2008 4:05 pm
Subject: Re: Re[2]: Hybrid GUI/Console App
Moin Vadim,
moin crjjrc,

> c> Considering that OnCmdLineParsed() is a member of wxAppConsole, I
> c> don't think this could be done since we are using the command-line
> c> arguments to figure which application to create.  Or am I missing
> c> something?

> I thought about deriving a wxGUIOrConsoleApp class from wxApp (i.e. the
> GUI version) but overriding its virtual Initialize() to call wxAppConsole
> version if argc != 1. I didn't test it but I think it should be possible to
> make this work.

Some (many?) GUI apps are capable to parse command lines, e.g. to detect which file to open etc. IMHO, just checking argc != 1 seems
too restrictive.

regards
Friedrich


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vadim Zeitlin  
View profile
 More options Apr 14, 4:07 pm
Newsgroups: comp.soft-sys.wxwindows
From: Vadim Zeitlin <va...@wxwidgets.org>
Date: Mon, 14 Apr 2008 22:07:27 +0200
Local: Mon, Apr 14 2008 4:07 pm
Subject: Re[4]: Hybrid GUI/Console App
On Mon, 14 Apr 2008 22:05:07 +0200 w...@61131.com wrote:

> > c> Considering that OnCmdLineParsed() is a member of wxAppConsole, I
> > c> don't think this could be done since we are using the command-line
> > c> arguments to figure which application to create.  Or am I missing
> > c> something?

> > I thought about deriving a wxGUIOrConsoleApp class from wxApp (i.e. the
> > GUI version) but overriding its virtual Initialize() to call wxAppConsole
> > version if argc != 1. I didn't test it but I think it should be possible to
> > make this work.

> Some (many?) GUI apps are capable to parse command lines, e.g. to detect which file to open etc. IMHO, just checking argc != 1 seems
> too restrictive.

 Yes, sure, it was just an example, we probably would want to use
wxCmdLineParser in some way if we wanted to do it properly anyhow.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
crjjrc  
View profile
 More options Apr 15, 10:56 am
Newsgroups: comp.soft-sys.wxwindows
From: crjjrc <crj...@gmail.com>
Date: Tue, 15 Apr 2008 07:56:59 -0700 (PDT)
Local: Tues, Apr 15 2008 10:56 am
Subject: Re: Hybrid GUI/Console App
On Apr 14, 2:53 pm, Vadim Zeitlin <va...@wxwidgets.org> wrote:

> c> Considering that OnCmdLineParsed() is a member of wxAppConsole, I
> c> don't think this could be done since we are using the command-line
> c> arguments to figure which application to create.  Or am I missing
> c> something?

>  I thought about deriving a wxGUIOrConsoleApp class from wxApp (i.e. the
> GUI version) but overriding its virtual Initialize() to call wxAppConsole
> version if argc != 1. I didn't test it but I think it should be possible to
> make this work.

I like this idea quite a bit.  I found I had a bit more to do to get
it to work, and more things probably remain.  I had to override
wxApp::CleanUp() since it too fiddled with GTK.  And I had to make
sure the active log target was stderr instead of wxLogGui.  It seemed
the most correct way to do this was derive a new wxAppTraits class and
override CreateLogTarget().

Here's the code, which now uses wxCmdLineParser:

------------
#include <iostream>
#include <wx/wx.h>
#include <wx/apptrait.h>
#include <wx/cmdline.h>

class HybridTraits : public wxGUIAppTraits {
   public:
      HybridTraits(bool gui_enabled)
         : wxGUIAppTraits(),
           gui_enabled(gui_enabled) {
      }

      wxLog *CreateLogTarget() {
         if (gui_enabled) {
            return wxGUIAppTraits::CreateLogTarget();
         } else {
            return new wxLogStderr;
         }
      }

   private:
      bool gui_enabled;

};

class GUITest : public wxApp {
   private:
      bool OnInit();

      bool Initialize(int& argc, wxChar **argv) {
         static const wxCmdLineEntryDesc desc[] = {
            { wxCMD_LINE_SWITCH, "c", "console", "run in console
mode" },
            { wxCMD_LINE_NONE }
         };

         wxCmdLineParser parser(desc, argc, argv);
         if (parser.Parse(true) != 0) {
            exit(1);
         }

         gui_enabled = !parser.Found("c");
         if (gui_enabled) {
            return wxApp::Initialize(argc, argv);
         } else {
            return wxAppConsole::Initialize(argc, argv);
         }
      }

      void CleanUp() {
         if (gui_enabled) {
            wxApp::CleanUp();
         } else {
            wxAppConsole::CleanUp();
         }
      }

      HybridTraits *CreateTraits() {
         return new HybridTraits(gui_enabled);
      }

      bool gui_enabled;

};

bool GUITest::OnInit() {

   wxString msg;

   if (gui_enabled) {
      msg = "in gui mode";
   } else {
      msg = "in console mode";
   }

   wxLogMessage(msg);
   return false;

}

IMPLEMENT_APP(GUITest);

------------

Vadim, if you think this would make a good sample, I'm happy to make
any changes to get it to a presentable state.

>  You can use wxCmdLineParser::ConvertStringToArgs() just as the code in
> src/msw/main.cpp does. But, again, hopefully this is unnecessary anyhow.

Good to know.  Thanks!

- Chris


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vadim Zeitlin  
View profile
 More options Apr 15, 1:39 pm
Newsgroups: comp.soft-sys.wxwindows
From: Vadim Zeitlin <va...@wxwidgets.org>
Date: Tue, 15 Apr 2008 19:39:35 +0200
Local: Tues, Apr 15 2008 1:39 pm
Subject: Re[2]: Hybrid GUI/Console App
On Tue, 15 Apr 2008 07:56:59 -0700 (PDT) crjjrc <crj...@gmail.com> wrote:

c> I like this idea quite a bit.  I found I had a bit more to do to get
c> it to work, and more things probably remain.  I had to override
c> wxApp::CleanUp() since it too fiddled with GTK.

 Sorry, what exactly was the problem? I think we should fix it in wxGTK.

c> And I had to make
c> sure the active log target was stderr instead of wxLogGui.  It seemed
c> the most correct way to do this was derive a new wxAppTraits class and
c> override CreateLogTarget().

 Indeed.

c> Here's the code, which now uses wxCmdLineParser:
c>
c> ------------
c> #include <iostream>
c> #include <wx/wx.h>
c> #include <wx/apptrait.h>
c> #include <wx/cmdline.h>
c>
c> class HybridTraits : public wxGUIAppTraits {
c>    public:
c>       HybridTraits(bool gui_enabled)
c>          : wxGUIAppTraits(),
c>            gui_enabled(gui_enabled) {
c>       }
c>
c>       wxLog *CreateLogTarget() {
c>          if (gui_enabled) {
c>             return wxGUIAppTraits::CreateLogTarget();
c>          } else {
c>             return new wxLogStderr;
c>          }
c>       }
c>
c>    private:
c>       bool gui_enabled;
c> };
c>
c> class GUITest : public wxApp {
c>    private:
c>       bool OnInit();
c>
c>       bool Initialize(int& argc, wxChar **argv) {
c>          static const wxCmdLineEntryDesc desc[] = {
c>             { wxCMD_LINE_SWITCH, "c", "console", "run in console mode" },
c>             { wxCMD_LINE_NONE }
c>          };
c>
c>          wxCmdLineParser parser(desc, argc, argv);
c>          if (parser.Parse(true) != 0) {
c>             exit(1);
c>          }
c>
c>          gui_enabled = !parser.Found("c");
c>          if (gui_enabled) {
c>             return wxApp::Initialize(argc, argv);
c>          } else {
c>             return wxAppConsole::Initialize(argc, argv);
c>          }
c>       }
c>
c>       void CleanUp() {
c>          if (gui_enabled) {
c>             wxApp::CleanUp();
c>          } else {
c>             wxAppConsole::CleanUp();
c>          }
c>       }
c>
c>       HybridTraits *CreateTraits() {
c>          return new HybridTraits(gui_enabled);
c>       }
c>
c>       bool gui_enabled;
c> };
c>
c> bool GUITest::OnInit() {
c>
c>    wxString msg;
c>
c>    if (gui_enabled) {
c>       msg = "in gui mode";
c>    } else {
c>       msg = "in console mode";
c>    }
c>
c>    wxLogMessage(msg);
c>    return false;
c>
c> }
c>
c> IMPLEMENT_APP(GUITest);
c>
c> ------------
c>
c> Vadim, if you think this would make a good sample, I'm happy to make
c> any changes to get it to a presentable state.

 Yes, I think this is a useful example and I'd be favourable to adding it
as a new sample. I don't have a good name for it though ("hybrid" is too
generic), do you?

 Thanks,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Fabian Cenedese  
View profile
 More options Apr 16, 5:16 am
Newsgroups: comp.soft-sys.wxwindows
From: Fabian Cenedese <Cened...@indel.ch>
Date: Wed, 16 Apr 2008 11:16:31 +0200
Local: Wed, Apr 16 2008 5:16 am
Subject: Re[2]: Hybrid GUI/Console App

>c> Vadim, if you think this would make a good sample, I'm happy to make
>c> any changes to get it to a presentable state.

> Yes, I think this is a useful example and I'd be favourable to adding it
>as a new sample.

I haven't tried this code, but when I once tried to create such an app
I was told that it's not possible on windows because the linker decides
the type of application with /SUBSYSTEM:WINDOWS or CONSOLE.

So how would this hybrid app now be created? Would it still have a
console attached even when using a GUI?

Thanks

bye  Fabi


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
crjjrc  
View profile
 More options Apr 16, 11:32 am
Newsgroups: comp.soft-sys.wxwindows
From: crjjrc <crj...@gmail.com>
Date: Wed, 16 Apr 2008 08:32:40 -0700 (PDT)
Local: Wed, Apr 16 2008 11:32 am
Subject: Re: Hybrid GUI/Console App
On Apr 15, 12:39 pm, Vadim Zeitlin <va...@wxwidgets.org> wrote:

> c> I like this idea quite a bit.  I found I had a bit more to do to get
> c> it to work, and more things probably remain.  I had to override
> c> wxApp::CleanUp() since it too fiddled with GTK.

>  Sorry, what exactly was the problem? I think we should fix it in wxGTK.

Well, the assertion failure occurs in wxApp::CleanUp in src/gtk/
app.cpp.  At last checkout, this was line 529.

void wxApp::CleanUp()
{
    if (m_idleSourceId != 0)
        g_source_remove(m_idleSourceId);

    // release reference acquired by Initialize()
    g_type_class_unref(g_type_class_peek(GTK_TYPE_WIDGET)); // line
529

However, I don't think we can say it constitutes a bug.  If I override
Initialize(), in which the GTK libraries are dynamically loaded and
which fails if they're not, I should probably expect that I need to
override any other wxApp functions that assume GTK is available.

>  Yes, I think this is a useful example and I'd be favourable to adding it
> as a new sample. I don't have a good name for it though ("hybrid" is too
> generic), do you?

guioptional?  guinogui?

I'm not sure how to address any Windows issues, since I don't have a
Windows machine to build on.  It was my understanding that wApps do
not show the console window at all, which would be the case here.
wxAppConsoles, on the other, optionally show the console window.

- Chris


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Vadim Zeitlin  
View profile
 More options Apr 17, 7:48 am
Newsgroups: comp.soft-sys.wxwindows
From: Vadim Zeitlin <va...@wxwidgets.org>
Date: Thu, 17 Apr 2008 13:48:36 +0200
Local: Thurs, Apr 17 2008 7:48 am
Subject: Re[3]: Hybrid GUI/Console App
On Wed, 16 Apr 2008 11:16:31 +0200 Fabian Cenedese <Cened...@indel.ch> wrote:

FC> I haven't tried this code, but when I once tried to create such an app
FC> I was told that it's not possible on windows because the linker decides
FC> the type of application with /SUBSYSTEM:WINDOWS or CONSOLE.
FC>
FC> So how would this hybrid app now be created? Would it still have a
FC> console attached even when using a GUI?

 Good question, I forgot about this issue to be honest. There is indeed a
problem with this under MSW because console applications always have a
console and while it can be explicitly destroyed with FreeConsole() it is
still visible on startup. And while Windows applications can be run from
the console, they don't have any console of their own. I thought that doing
::AttachConsole(ATTACH_PARENT_PROCESS) could help here but this function
fails for me (Windows 2003) with "invalid handle" error and, anyhow, it's
XP and later only. And in fact even allocating a new console doesn't work
(the console does appear but printf() still does nothing).

 So it unfortunately seems that the usefulness of this method under Windows
is indeed limited to console applications which sometimes need to show GUI.

 Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
               http://www.tt-solutions.com/


    Reply to author    Forward