Can anyone make sense of this?

This is a discussion on Can anyone make sense of this? within the C++ Programming forums, part of the General Programming Boards category; Resolved Function That works: Code: // Prints out per-line at speed of delay in milliseconds for "int lines" amount of ...

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    66

    Can anyone make sense of this?

    Resolved Function That works:
    Code:
    // Prints out per-line at speed of delay in milliseconds for "int lines" amount of lines
    bool ScrollText(char Msg[MAX_LENGTH], int lines, int delay, int tabs)
    {
    	using namespace std;
    
    	CONSOLE_SCREEN_BUFFER_INFO	consoleSBI;
    	COORD						tabCoord;
    
    	// Get our cursor position
    	if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleSBI))
    		return false;
    
    	// Set X to equal 0
    	consoleSBI.dwCursorPosition.X = 0;
    	// Add 1 to Y
    	consoleSBI.dwCursorPosition.Y += 1;
    
    	// Set our cursor position
    	if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    		return false;
    
    	// Display any tabs the user wishes to use
    	for (int i=tabs;i>0;--i)
    	{
    		// Instead of actually displaying tab characters, we will
    		// set the cursor indented in by x amount of tabs
    		// which is every 8 columns from the left if you start at
    		// the left-most side of the screen
    		consoleSBI.dwCursorPosition.X += 8;
    	}
    
    	// Set tabCoord
    	tabCoord.X = consoleSBI.dwCursorPosition.X;
    	tabCoord.Y = consoleSBI.dwCursorPosition.Y;
    
    	// Set our cursor position
    	if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    		return false;
    
    	for (i=0;i<lines;++i)
    	{
    		// Progress line-by-line
    		consoleSBI.dwCursorPosition.Y = tabCoord.Y;
    		for (int k=i+1;k>0;--k)
    		{
    			consoleSBI.dwCursorPosition.Y += 1;
    			// Set our cursor position
    			if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    				return false;
    			// Overwrite the previous data to erase it
    			for (int j=strlen(Msg);j>0;--j)
    			{
    				cout << " ";
    			}
    		}
    		// Set our cursor position
    		if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    			return false;
    
    		// Display the message
    		cout << Msg;
     
    		// Pause for int delay
    		Sleep(delay);
    	}
    
    	// Clean out cout buffer
    	cout.flush();
    	return true;
    }
    Last edited by tjpanda; 10-13-2007 at 12:06 AM. Reason: Resolved. Thanks for the help ^^

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by tjpanda View Post
    I was working on a function that would display a message on one line, then print it on the next line while erasing it on the previous line, and keep doing that until it had printed it on the "int lines" line. IE:

    Code:
    ScrollText("Hello!", 3, 200, 0);
    Should output:

    Code:
    Iterate once:
    [Hello!]
    
    Iterate twice:
    [
    Hello!]
    
    Iterate Three times:
    [
    
    Hello!]
    Where the "[" and "]" tags represent the console window, anyhow, so the function works for what I need it to right now, but I'm really not really sure...why.

    Should I accept it as magic, or keep looking into it in case of future problems?

    Code:
    // Prints out per-line at speed of delay in miliseconds for "int lines" amount of lines
    int ScrollText(char Msg[MAX_LENGTH], int lines, int delay, int tabs)
    {
    	using namespace std;
    	string scroll = "\n";
    
    	CONSOLE_SCREEN_BUFFER_INFO consoleSBI;
    
    // Get info about the "screenbuffer" - we only really need the cursor postion.
    	if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleSBI))
    		return GetLastError();
    
    
    	for (int i=0;i<lines;++i)
    	{
    // Add a '\n' to the scroll string.
    		scroll.append("\n");
    // sleep for delay milliseconds, e.g. 200 ms in your example
    		Sleep(delay);
    
    Move cursor to the position where it used to be.
    		if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    			return GetLastError();
    
    		// Create a blank space on every line up to the current line
    		// *For the record I am slightly hazy on how this works*
    		// *alot of testing and luck got me this next bit of code*
    // Output a bunch of tab characters - this will "erase" the old text.
    		cout << "\n";
    		for (int k=i;k>0;--k)
    		{
    			for (int j=strlen(Msg)-1;j>0;--j)
    			{
    				if ( tabs == 0 )
    					cout << "\t\t";
    
    				for (int n=tabs;n>0;--n)
    					cout << "\t";
    			}
    		}
    
    // Move cursor back to original position
    		if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    			return GetLastError();
    			
    // Output "i+1" newlines.
    		cout << scroll;
    // Output "tabs" tab characters.
    		for (k=tabs;k>0;--k)
    			cout << "\t";
    
    // Output the message.
    		cout << Msg;
    	}
    // Hmm - the rest of the function returns an error code. This probably should be "EXIT_SUCCESS" instead of "TRUE".
    	return true;
    }
    Comments in red above.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Oct 2007
    Posts
    66
    Thanks, I should have been more specific though, the only part I was confused about was the tabs erasing the text, not sure why that works. But thanks for pointing out the return true; -- originally it was a bool function but I was debugging it and needed to find out error codes so I went ahead and changed it.

    However if you say the tabs erase it that makes more sense, I was wondering what exactly happens when I output the tabs on the line, because if I set 0 tabs in the function parameters and then I only put 1 tab per line it acts odd, but two seems to clear the line.

    I'm worried I'm going to want to later on sometime scroll text behind pre-existing text so I don't want this to over-write the pre-exisiting text, though maybe I should just say tab is 4 spaces, (I think, I'll test it in a minute) and then say "strlen(Msg) / 4 = x amount of times I will tab" then maybe % to see if anything is left-over, and whatever is left over I just add a \0 to or something, hm...
    "When your work speaks for itself - don't interrupt!"

    -Samantha Ingraham.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Generally, a tab translates to "enough spaces to the next column multiple of 8". You could just print enough spaces to cover the length of the string.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    66
    Ah, so it's 8 not 4, ok. Printing spaces for the entire string length seems to be a better idea too, thanks

    --Combining below post so I don't double post my bad :x

    Hmm, this is what I have managed to come up with then. It should work perfectly fine with any length string and any amount of tabs and it only affects the text on the lines that have text being scrolled to, but not past the last character displayed in the string. It'd be cool to be able to not over-write what was on the left-side of the scrolling text that has been tab'd but I'm not sure if that's possible, any ideas?

    Code:
    // Prints out per-line at speed of delay in milliseconds for "int lines" amount of lines
    bool ScrollText(char Msg[MAX_LENGTH], int lines, int delay, int tabs)
    {
    	using namespace std;
    	string scroll = "\n";
    
    	CONSOLE_SCREEN_BUFFER_INFO consoleSBI;
    
    	// Get our cursor position
    	if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleSBI))
    		return false;
    
    	for (int i=0;i<lines;++i)
    	{
    		// Progress down another line and pause for int delay
    		scroll.append("\n");
    		Sleep(delay);
    
    		// Set our cursor position back to the original cursor position
    		if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    			return false;
    
    		// Create a blank space per character in Msg on every line up to the current line
    		// Effectively "erasing" the trail by overwriting the characters
    		cout << "\n";
    
    		// Progress line-by-line
    		for (int k=i;k>0;--k)
    		{
    			cout << "\n";
    			
    			// Display any tabs the user wishes to use
    			for (int n=tabs;n>0;--n)
    					cout << "\t";
    			// Overwrite the previous data to make it look invisible
    			for (int j=strlen(Msg);j>0;--j)
    			{
    				cout << " ";
    			}
    		}
    
    		// Set our cursor position back to the original cursor position
    		if(!SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consoleSBI.dwCursorPosition))
    			return false;
    
    		// Display the message on the new line
    		cout << scroll;
    		for (k=tabs;k>0;--k)
    			cout << "\t";
    		cout << Msg;
    	}
    	// Clean out cout
    	cout.flush();
    	return true;
    }
    EDIT:

    Wait I know, I could just modify the x value of the cursorposition and set that to be +8 per tab, making sure it starts at the leftmost side of the screen of course, and then I would ONLY over-write the text I wrote, yay!
    Last edited by tjpanda; 10-12-2007 at 03:51 PM. Reason: Didn't realize I double posted, sorry!
    "When your work speaks for itself - don't interrupt!"

    -Samantha Ingraham.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Does this even remotely make sense
    By hckr83 in forum C Programming
    Replies: 6
    Last Post: 12-23-2005, 05:02 PM
  2. want to make this small program...
    By psycho88 in forum C++ Programming
    Replies: 8
    Last Post: 11-30-2005, 02:05 AM
  3. Question about atheists
    By gcn_zelda in forum A Brief History of Cprogramming.com
    Replies: 160
    Last Post: 08-11-2003, 12:50 PM
  4. 'functions' in make?
    By mart_man00 in forum C Programming
    Replies: 1
    Last Post: 06-21-2003, 03:16 PM
  5. Foreigners don't make sense
    By Shadow in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 04-25-2002, 03:31 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21