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?
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!
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.
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).
Related
I have two loggers in my program. One that I made inside a gui, and one that is super complicated but very well designed and prints to the console. I am trying to get the output from the nice console logger to the rendered one. I have tried everything under the sun to get this to work but I can't seem to figure it out (due to my lack of understanding of the code from the other logger(spdlog).) My conclusion is that taking the logs directly from what is printed is the best way to do this but I can't find online anyone asking how to do this. I have seen a few questions but they just post code as an answer and don't really explain what is going on. My question: Is there a way to grab printed statements from the console and what are the performance issues/complications that come with doing something like this.
For example, if i do std::cout << "hello!" << std::endl; or some printf statement, I want to be able to further down in the code be able to grab "hello!"
My conclusion is that taking the logs directly from what is printed is the best way to do this but I can't find online anyone asking how to do this.
Consoles nowadays are terminal emulators. The original terminals' output went to printers and couldn't be (easily) read back.
Application's stdout and stderr (console) streams are write-only. Moreover, in Windows and Unix/Linux you can pipe your program's (console) output (either or both stderr and stdout) into another application with | (pipe) that creates a pipe IPC between stdout of your application and stdin of another one. That IPC pipe is write-only, your application cannot possibly read back from it.
You may be able to get access to the contents of the frame buffer of Windows cmd.exe that controls its Windows console window, but that won't be the verbatim byte-exact copy of data you wrote into stdout because of the escape sequences interpreted by Windows console.
If stdout is redirected into a file you can re-open that file for reading, but there is no portable way to re-open that file.
In other words, there is no portable way to read console output back.
I have tried everything under the sun to get this to work but I can't seem to figure it out (due to my lack of understanding of the code from the other logger(spdlog).
I bet you haven't tried reading spdlog documentation, in particular logger with multi sinks. A sink is an output abstraction, which implementation can write into a file, memory or both. What you need is attach your own sink to spdlog that prints into your UI.
Derive your sink from base_sink and implement abstract member functions:
virtual void sink_it_(const details::log_msg &msg) = 0; to print into the UI, and,
virtual void flush_() = 0; to do nothing.
Then attach one object of your sink class to that spdlog.
I have a C++ console application that prints some output constantly while it also accepts commands (using std::cin) from the user - output and input happen in separate threads.
If I write a text while some output appears the written text is mixed with application output. How can I prevent this behaviour?
To solve this problem, I need to display the program one line above the line where the text is typed. I'd inspire myself in Minecraft Bukkit server's solution - however I need the same for C++.
Assuming you want the output to appear while things are being typed, you'll need some screen control facilities to have the output go somewhere different than the input area. If I were tasked to implement something like this writing to a terminal I would refresh my ncurses experience. I realize you are on a Windows console and I have no idea if the Windows console is capable of the screen control needed to make it happen.
You can possibly tie custom stream buffers into std::cin and std::cout using the curses functionality under the hood but it may not be worth it. In any case, it isn't entirely trivial.
There's a windows port of ncurses called pdcurses. But if you are using visual studio there's a simple function provided called SetConsoleCursorPosition()
I am working on a windows sever program using c++, when the program started it stays for several days and output important logs to the default windows console.
now I want to add some control function to the console, like I cound enter something like query or stop, and the program ouput the variable number or stop accept requests. So there is the problem, I got two output stream(log and query response) and one input stream both mixed in one single console.
How do I seperate the three different stream in one single console? Maybe I cound write my own console to replace the default windows console?
I believe this is a very normal need and a lot of server application has implemented this but I could not find any source code...
I know I could use ncurses, but I think ncurses seems too low level for this. Any suggestion will be apprecitated.
First, a bit of background: I'm running the latest stable build of Crunchbang Linux inside a VirtualBox VM. I'm designing a custom text-based user interface to run on top of bash. This is being done with a combination of C++ and bash scripts.
I need to, at times, completely and totally remove the ability for the user to provide the system with any sort of standard keyboard input. This is because, when I run a part of the system, the user is forced to wait for certain amounts of time.
Unfortunately, the user can still type while this is going on, and whatever they type is put on the screen. This happens when I'm running a C++ program as well as a bash script. The reason this is a problem is that there is text on the screen which the user is to read, and if they can type, it displaces the text. There will be other uses for this later, as well, like making the system seem like it has frozen up.
So, the question - How do I
disable the keyboard, or
prevent anything pressed on the keyboard from showing up on the screen?
Turn off echo mode with stty -echo or the equivalent C code (which would use tcgetattr and tcsetattr). When you are ready to accept input again, turn it back on. You may also wish to discard the input that arrived while you weren't expecting it. That would be done with tcflush but be aware that some users (like me) would consider that an annoyance. Typeahead is a feature, not a bug!
To see how user input to a certain process or tty can be intercepted, the man page and source code of interceptty may be enlightening. (have no experience with it)
However, you can hardly (totally) prevent user input. The user is probably always able to switch to a different virtual terminal (if any) or at least to reboot the system with Alt+Print+B (Magic SysRq_key) if not disabled. It is two different things to ignore input on a given tty and disabling keyboard input altogether.
As you can see in u413.com: Text comes on the screen, letter by letter, which looks kind of cool,
I want to do the same thing in Console
I got the source code of version 1.2; because I dont need all the complexity of version 2;
I just need a simple Command Prompt, with text that comes on to the screen letter by letter.
I dont need most of the builtin functions offered by Console, like Transparency, Taskbar Icon, etc.
The source code base is pretty small with only about 5 files.
The main class file seems to be Console.cpp;
Since console is like a GUI application, things dont get written to the STDOUT.
but heres what happens;
A Handle is called;
And that handle apparently writes to the console;
m_hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
Now what I want to be able to do; Is somehow read the handle; see what text it has; And throw in a loop with a ::Sleep(20) method in it; to make sure that text appears letter by letter.
#Alf P. Steinbach I wrote the psuedo code for making the sleep command(in java) I also made use of it in every other java program I wrote, but the disadvantage was that it will work only for my programs and not every program run in the command prompt, but what I dont know is code to make a console, a windows console subsystem program, I wish it was possible with java, so that I could use it on linux too, but now, let me ask you exactly what I had in mind...
A program which simply, took input from the screen, send it to cmd.exe for processing, and sent back the reply, and all I have to do is throw in a sleep command between every character...
All I need is help, in getting this done, I wish you could start me up with this, and possible provide links and refrences to get this done...
This Console.cpp seems like a console emulator, meaning it runs OTHER programs. You don't need the source code, you can run existing console applications.
STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE are the windows handles for STDIN, STDOUT and STDERR. They basicly does the same with only a few differences in how to use it.
If you want to integrate the console into your code, then you have to understand it, and find its own output function and call that. But it won't be any standard handle or things like that.