How to write console applications with Delphi
Posted: (EET/GMT+2)
Today, most Windows applications use the graphical user interface (GUI) with windows, menus, buttons and so on. Still, power users, like programmers sometimes prefer command line tools, which are almost exactly like good old DOS (or even better Unix) programs: efficient and powerful, but often with arcane UIs.
However, the UI mustn't be bad. Did you know that Win32 console applications can use color, menus, buttons and even the mouse? Actually, console applications can do very sophisticated things -- the whole Win32 API is in use. Of course, writing a "normal" GUI program is easier, but for some tools, like programming utilities, the console mode is great (at least IMHO ;-).
Writing a simple console program is easy: you simply specify that your application is a console application with the $APPTYPE compiler directive or the Delphi IDE, and then use the Write(Ln) and Read(Ln) functions to write and read from the console, respectively.
If you have ever programmed in DOS with Borland's Turbo Pascal for example, you will remember the CRT unit, which had helpful functions that dealt with the "cathode ray tube". However, Delphi doesn't include this unit anymore, so you are left alone with the APIs.
Fortunately, the APIs are quite easy, and what's even better, I've written a simple unit which is similar to the CRT unit. For example, to clear the console screen, you call the ClrScr procedure. And to set the text color, you call the SetTextColor procedure.
To demonstrate what you can do with the unit (which is named "Console"), I've written a simple and very stupid demo program. It draws some colored characters rather randomly without any real world use, but as said, it is just a demo.
Far more interesting is what goes inside the unit. Of course, I don't have the time to describe everything here, but as you have the code, you can check it yourself.
When you use the console APIs, you almost always need an input or output handle. Unless you need special effects like in the new Star Wars movie, you can get this handle by calling the GetStdHandle function, like this:
StdInput := GetStdHandle(std_Input_Handle); StdOutput := GetStdHandle(std_Output_Handle);
When you want to clear the "screen" with the ClrScr procedure, the following code is executed:
... Var Len,Dummy : Integer; Begin Len := MaxX*MaxY; FillConsoleOutputAttribute(StdOutput,cbBlack+cfWhite,Len,NullCoord,Dummy); FillConsoleOutputCharacter(StdOutput,#0,Len,NullCoord,Dummy); GotoXY(1,1); End;
To clear the screen, we must first calculate how many characters the screen holds (you can get the size of the screen with the GetConsoleScreenBufferInfo function). Then we simply fill the screen with the dark gray color, and then clear it by writing null characters.
Setting the cursor position is easy with the GotoXY function, which internally uses SetConsoleCursorPosition API function. As easy as setting the position is querying it: simply use the WhereX and WhereY functions.
The unit also has other functions, like ClrEol, SetTitle and ReadKey, which are self-evident to use. However, for example the KeyPressed function is quite complex, and describing it is beyond the scope of this How To. If you want to understand it, simply check the used API functions in on-line help to learn what they do.
Anyway, I hope this unit will get you started with console programming. Don't let the "black screen" die!