4

I have a problem with my application win32 console.

The console is used to give commands to my application. However, at the same time it is used to output log messages which mostly comes from asynchronous threads. This becomes a problem when the user tries to write some input and simultaneously an async log message is printed, thus thrashing the display of the users input.

I would like to have some advice in regards to how to handle such a situtation?

Is it possible for example to dedicate the last line in the console to input, similarly to how it looks in the in-game consoles for some games?

ronag
  • 49,529
  • 25
  • 126
  • 221

3 Answers3

6

You can use SetConsoleMode to disable input echo and line editing mode. You can then echo back input whenever your program is ready to do so. Note that this means you will need to implement things like backspace manually. And don't forget to reset the mode back when you're done with the console!

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • Would you mind providing an example? I'm a bit confused as to what to make of the information provided in your link. The user still needs to see what he/she has written so far while writing commnads. From what I understand in your example then the input can only be displayed once all of it has be written.. – ronag Feb 04 '11 at 14:30
  • 1
    +1, but he'd still need to synchronize his "echoing thread" somehow with those other threads, or he'd get the same problem. – T.E.D. Feb 04 '11 at 14:43
  • @ronag, if you disable the line editing mode (clear ENABLE_LINE_INPUT), you will get characters immediately as they are typed. You are then free to display them in any way you see fit, whenever you see fit. – bdonlan Feb 04 '11 at 14:55
  • Not to be difficult but, the question then becomes how can I display them properly in the console window? If I display what the user has written so far and a log message is sent, then the log message will break the displayed input... – ronag Feb 04 '11 at 15:02
3

This is possible using the Console API, but it involves quite a bit of work and all the threads that use the console will have to cooperate by calling your output method rather than directly calling the Console API functions or the runtime library output functions.

The basic idea is to have your common output function write to the console screen buffer, and scroll the buffer in code rather than letting the text flow onto the last line and scroll automatically. As I recall, you'll have to parse the output for newlines and other control characters, and handle them correctly.

You might be able to get away with using "cooked" console input on the last line, although in doing so you risk problems if the user enters more text than will fit on a single line. Also, the user hitting Enter at the end of the line might cause it to scroll up. Probably best in this situation to use raw console input.

You'll want to become very familiar with Windows consoles.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
2

Any time you have asyncronous threads trying to update the same device at once, you are going to have issues like this unless something synchronizes them.

If you have access to everyone's source code, the thing to do would probably be to create some kind of sync object that every task must use to access the console (semaphore, etc).

T.E.D.
  • 44,016
  • 10
  • 73
  • 134
  • I don't see how synchronization solves the problem. If I have a semaphore then either input is blocked, our output is blocked until the user has finished the command, not optimal. What I need is something like a line where input can be written but no output. Similar to how irc consoles usually work. – ronag Feb 04 '11 at 14:45
  • @ronag - Even in the case of IRC consoles, if you crack open the code you will find that there is only one thread allowed to update the console at a time. That doesn't mean you have to prevent all output until the user is done typing. See bdolan's answer above. – T.E.D. Feb 04 '11 at 15:54