Console Menu with Blinking Start Button and Unintrusive Input

Here is the code I'm working on in main()...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    
///////////////////////////////////////////////
bool start = false;

while (start == false)
{
    gotoxy(35, 18);
    cout << "(s) Start";
    sleep_for(nanoseconds(1000000000));
    gotoxy(35, 18);
    cout << "         ";
    sleep_for(nanoseconds(500000000));
}

while (start == false)
{
    char key = ' ';
    key = _getch();
    if (key == 's')
    {
        start = true;
    }
}
//////////////////////////////////////// 


The idea is to run the loop that waits for the proper input while simultaneously running the other loop (which is blinking text). Or maybe you can think of a way to get it to work without multithreading? I can't figure it out.

Thanks in advance

PS - I moved this from the beginner forum but I can move it back if it's more appropriate there.
Last edited on
Am I not providing enough information or something?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <atomic>
#include <thread>
#include <future>

void blink( unsigned int interval_msecs, std::atomic<bool>& keep_at_it )
{
     while( keep_at_it )
     {
         std::cout << "blink " << std::flush ;
         std::this_thread::sleep_for( std::chrono::milliseconds(interval_msecs) ) ;
     }
}

int main()
{
     std::cout << "enter 'q' to stop blinking\n" ;
     std::atomic<bool> keep_blinking(true) ;
     // http://en.cppreference.com/w/cpp/thread/async
     auto future = std::async( std::launch::async, blink, 500, std::ref(keep_blinking) ) ;

     char c ;
     while( std::cin >> c && c != 'q' ) ;
     keep_blinking = false ;
     future.wait() ;
}
Thank you so much!

This is perfect, this little bit of code is teaching me a lot, I owe ya one.
Ok, so there are definitely some kinks I need to straighten out, but I'm gonna take a crack at it and I'll let you guys know my solution.
Ok, so I have my code working at this point. This is what I've come up with, thanks to the help from JLBorges!

As you will see, before main, I have the gotoxy() function and the blink() function.

gotoxy() - allows you to place the blinking text wherever you want. I wasn't able to
get it to behave the way I wanted, so you will notice I had to insert a bunch of spaces in
the cout portion of the blink function. Obviously this could be refined.

blink() - thanks again to JLBorges for this function. I made a small adjustment in that I
put a /r to set the cursor back to the beginning of the line, and then after a brief
pause, I put another cout function with blank spaces and a /r. This gives the
blinking effect.

If you take a look at main, you will see that I changed it up a bit, the biggest change being the insertion of the gotoxy() function and the while() loop.

The while loop - allows the program to detect a specified key input "behind the scenes"
so to speak. This means that it won't show a cursor, the input from the keyboard, insert
a new line, space, or require the user to press enter. It simply waits for a specific key
to be pressed before continuing the program.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// i'm honestly not sure which of these are necessary for this particular snip of code //
#include <iostream>
#include <conio.h> 
#include <Windows.h>
#include <chrono> 
#include <thread> 
#include <atomic>
#include <future>
//////////////////////////////////////////////////////////////////////////////////////////////////////

// set cursor x/y position //
void gotoxy(int column, int line)
{
	COORD coord;
	coord.X = column;
	coord.Y = line;
	SetConsoleCursorPosition(
		GetStdHandle(STD_OUTPUT_HANDLE),
		coord
		);
}
////////////////////////////////

// blinking start function //
void blink(unsigned int interval_msecs, std::atomic<bool>& keep_at_it)
{
	while (keep_at_it)
	{
		std::cout << "                                    (s) Start\r" << std::flush;
		std::this_thread::sleep_for(std::chrono::milliseconds(interval_msecs));
		std::cout << "                                             \r" << std::flush;
		std::this_thread::sleep_for(std::chrono::milliseconds(interval_msecs));
	}
}
///////////////////////////////

// MAINMAINMAIN //
int main()
{
	// wait for 's' to proceed //
	gotoxy(0, 18);

	std::atomic<bool> keep_blinking(true);

	auto future = std::async(std::launch::async, blink, 500, std::ref(keep_blinking));

	bool start = false;

	while (start == false)
	{
		char key = ' ';
		key = _getch();
		if (key == 's')
		{
			start = true;
		}
	}
	///////////////////////////////
}
////////////////// 
Last edited on
Topic archived. No new replies allowed.