How to convert a MFC application with a GUI to a GUI-less executable?

I have a desktop application written Microsoft Visual C++ using Visual Studio 2017.  Its a single-doc MFC application.   Rather large, developed over the past 15+ years.  Now I want to be able to do something different: normally, of course, the application starts up and shows its GUI on the screen.  I want to add a mode (will have the App check for the presence of a certain file at start up) in which it does not pop its GUI up.  Ultimately, I'd like to have the ability to run it either A) with its GUI as usual, or B) as a GUI-less executable, probably in a windows service.  The app contains a socket-based message system that listens for commands and sends responses -- so when it is running in GUI-less mode, it will be another program talking to it over this socket channel in order to have it do useful work.

So, how to do this?   Maybe forget about the windows service idea for now -- just simply how to start my application and have it run without ever popping a GUI?   The structure, due to MFC, with the Doc, the View, the InitInstance code, the MainFrame class -- all that stuff is kind of mysterious to me.  I just used the structure that the MFC wizard gave me (when I first created this App back in Vis Studio version 6!).  Now it seems I may need some understanding of how to launch the system, but without Mainframe and the View popping up, etc.  Some of the Apps actions occur due to "OnTimer" code which might be on a dialog class -- so it seems to me I'd have to rework that perhaps -- there won't be a windows message loop running, so maybe OnTimer stuff won't run?

Thanks if you can give me some hints to try.
Who is Participating?
Kevin StanushConnect With a Mentor Application DeveloperCommented:
It depends on what your application is going to do.  What I meant  to say is that you would (when running non-GUI) call a function that would carry out a task, then just return FALSE.  But if you want your application to run and stay running, just not have a GUI, you could just hide the GUI first.  Do that by changing the ShowWindow to have one of the other windows settings:

This would allow you to effectively 'hide' the GUI.  You could also not initialize some of your GUI controls, but it depends if the functions you need are in those classes or not.

I assume when the application is running non-GUI, you have some way to talk to it including telling it to exit.

So my original technique is sort of like this:

To hide the GUI, use something like this:

Using SW_HIDE should work, just remember, you won't have a window, so any code that does anything that needs a window needs to check to see if there is one first.
David Johnson, CD, MVPOwnerCommented:
the only way I can think of doing this is have a launchpad.exe that checks for the gui flag and depending upon the flag launch another application i.e. gui version, console version.
Kevin StanushApplication DeveloperCommented:
In your CWinApp class, which will be a really small .cpp file, you will have an ::InitInstance function.  It will be created automatically by the wizard you used and generally does not do much.  It can access the command line (m_lpCmdLine), or you can check for your file here, and if you want to kill the GUI, call some other function here; you can even call a function in CMainFrame.  Then, just:

return FALSE;

...that will terminate the app without a GUI.  But let your current InitInstance do everything it does now, put your 'GUI-less' code at the bottom.

There may be other ways, but that is how we do it.
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

tullheadAuthor Commented:
Kevin - I made a small test application (rather than using my *huge* one) -- so I can play with ways to trick the MFC structures into letting me run with no GUI.

OK, if I simply have InitInstance return false, then the App just ends, which is no good -- its not running GUI-less.

Then I placed a Sleep(20000); at the end of InitInstance, and changed InitInstance to return false -- I thought this might get me 20 seconds of running with no GUI, and then it would exit.  But.... the GUI still pops up, and then it exits 20 seconds later.

Then I noticed that the wizard-generated code has a statement pMainWnd->ShowWindow(SHOW) -- so I took that out -- but... it *still* shows the GUI!

So, I'm going to continue, just thought I'd see if you could clarify the method you suggest.  Thanks!
tullheadAuthor Commented:
Kevin - OK, so I found that I must also comment out the line

 if (!ProcessShellCommand(cmdInfo)) return FALSE;

If that line is in my InitInstance, then the GUI pops up -- now that its gone, it seems to be running GUI-less!  Yeah!  A bit more testing...
Kevin StanushApplication DeveloperCommented:
Glad you got some progress.  It does take some playing around and lots of testing, especially if calling code that would normally run in a GUI.
tullheadAuthor Commented:
Yes, I think I see the basics of how to do it -- but now, there are a lot of details in places where my code might assume there are GUI controls in existence....  so I'll get on to all that now.  Thanks for your help!
tullheadAuthor Commented:
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.