Delphi allows to write Console applications as well as GUI applications, while the latter is the default.
But “Console” application is not clearly defined in the documentation as I found out only today (and I have been programming in Delphi for about 20 years).
There is the {$AppType Console} compiler directive which corresponds to the /cc compiler switch and which has no corresponding setting in the compiler options dialog. The File -> New -> Console Application menu generates a project containing this directive. As documented in the Delphi online help this compiler directive opens the INPUT and OUTPUT files which are associated with the stdin and stdout handles. In addition, at least since Delphi 2007 it also opens the ErrOutput file which is associated with the stderr handle. (The latter doesn’t seem to be documented.) Also, the IsConsole function returns true for programs compiled with this directive. The conditional symbol CONSOLE is not defined for these programs unless you also set the linker option "Generate console application". (Which is odd. Why should a linker option have any effect on a conditional symbol for the compiler? But that’s how it is.)
Then, there is the linker option "Generate console application". This option is not automatically set if you use the File -> New -> Console application menu. If you set it, the conditional symbol CONSOLE is defined. You can also set this option for a GUI program. In this case, CONSOLE also defined and in addition to your program’s form, you will also get a console window. Also IsConsole returns true and the files INPUT, OUTPUT and ErrOutput are opened.
So there are four possible combinations:
- AppType CONSOLE + "Generate console application" is set -> CONSOLE is defined and IsConsole returns true
- AppType GUI + "Generate console application" is set -> CONSOLE is defined and IsConsole returns true
- AppType CONSOLE + "Generate console application" is not set -> CONSOLE is not defined and IsConsole returns true
- AppType GUI + "Generate console application" is not set -> CONSOLE is not defined and IsConsole returns false
I could not find any difference between the cases 1 and 2. Maybe some additional startup code is generated in one of these cases? But the executable size doesn’t seem to change either. So, what is the actual point of the compiler directive?
So the important lesson here is:
The files INPUT, OUTPUT and ErrOutput are opened automatically if IsConsole returns true, regardless of the conditional symbol CONSOLE. I don’t really see the use of the latter.
For the curious here is the program code I used to find out the above:
program ConsoleTest; {.$APPTYPE CONSOLE} uses Windows; begin {$IFDEF CONSOLE} WriteLn('CONSOLE is defined'); {$ELSE} if IsConsole then WriteLn('CONSOLE is not defined') else Windows.MessageBox(0, 'CONSOLE is not defined', nil, MB_OK or MB_ICONINFORMATION); {$ENDIF} if IsConsole then begin WriteLn('IsConsole returns true'); WriteLn('Press Enter'); Readln; end else begin Windows.MessageBox(0, 'IsConsole returns false', nil, MB_OK or MB_ICONINFORMATION); end; end.