Generally, when you don't want a console, you should choose the "GUI" or "Windows" subsystem (depending on what your development environment elects to call it). That controls which bits the linker sets in your EXE header. You can't control the subsystem after your program has started running because the OS readers your EXE file and determines the subsystem to use before executing any code in your program.
Using the Windows subsystem does not require that you have any windows; it just tells the OS when it's loading your program that you don't need a console. It has nothing to do with whether you use any Windows APIs. Both subsystems are full-fledged Windows applications and offer full use of Windows API functions.
You can do all the same things from WinMain
as you can from main
. There are functions for fetching the command line and splitting it into separate arguments.
However, if you don't want your main function to be called WinMain
then you cannot use the Windows subsystem. The choice of subsystem also controls which set of preparatory code the linker puts in your program. The preparatory code is where the real entry point of your program lives, and it's what initializes the C++ standard library and calls the constructors of any objects with namespace scope. The code included in console mode calls main
(or wmain
); the code linked for the Windows subsystem calls WinMain
(or wWinMain
). If you use the Windows subsystem and don't define a function named WinMain
, then you will get errors when you link; the linker will complain about an undefined function. (You do not have to include windows.h to define WinMain
, if inclusion of that header is what you're afraid of.)
Since the subsystem to use is just a set of bits in the EXE header, you change change it after linking has occurred with the editbin
program. When you link, select the console subsystem so you get the console preparatory code and main
, and then modify the binary to use the Windows subsystem instead:
link foo.obj /out foo.exe /subsystem:CONSOLE
editbin /subsystem:WINDOWS foo.exe
Then your program will run without a console. Beware that if there are any problems while starting up, the preparatory code might crash your program because it was written expecting to have a console available to write to, but it won't be there.