manipulating the cursor position.

Jul 26, 2016 at 8:04am
i am making a part of a game that requires a function to control the cursor, in theory what i wrote must work perfectly but i cant understand where is the problem.
because it doesn't change the values of CoordX and CoordY past 1 and always prints Error.

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
#include<windows.h>
#include<conio.h>
#include<iostream>
using namespace std;

int Detected_Key;

  class {
// the class should allow us to disable certain buttons when needed.
public:
	bool Up_Arrow = true;
	bool Down_Arrow = true;
	bool Left_Arrow = true;
	bool Right_Arrow = true;
	bool Enter_Key = true;
}Set;

void Set_Cursor_Position(short CoordX, short CoordY)
//our function to set the cursor position.
{
	HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD position = { CoordX,CoordY };

	SetConsoleCursorPosition(hStdout, position);
}

void Navigation(short Skipper, short CoordX, short CoordY)
{
	Detected_Key = _getch();
	switch (Detected_Key)
	{
	case 72:
		if (Set.Up_Arrow == true) { CoordY -= Skipper; Set_Cursor_Position(CoordX, CoordY); }
		break;
	case 80:
		if (Set.Down_Arrow == true) { CoordY += Skipper; Set_Cursor_Position(CoordX, CoordY); }
		break;
	case 75:
		if (Set.Left_Arrow == true) { CoordX -= Skipper; Set_Cursor_Position(CoordX, CoordY); }
		break;
	case 77:
		if (Set.Right_Arrow == true) { CoordX += Skipper; Set_Cursor_Position(CoordX, CoordY); }
		break;
	case 13:
		if (Set.Enter_Key == true) { /* do something */ }
		break;
default: cout << "Error";
break;

	}
}
Jul 26, 2016 at 8:10am
closed account (48bpfSEw)
 
void Navigation(short Skipper, short CoordX, short CoordY)


the parameters are passed by value and not by reference : &CoordX, &CoordY
Jul 27, 2016 at 10:16am
when i pass by value it wants me to declare 2 extra variables is there any way to do it without reference ? (not using GetAsynKey).

edit: i entered 2 test variables and now the position changes perfectly but there is still a problem it prints error as if the default in the switch case is triggered every time you press any button.
Last edited on Jul 27, 2016 at 10:27am
Jul 27, 2016 at 4:43pm
Ditch the variables CoordX and CoordY.
Use the Windows API to query the current cursor position.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename T>
T Clamp( T low, T value, T high )
{
  return std::max( low, std::min( value, high ) );
}

void Move_Cursor_Relative( int offset_X, int offset_Y )
{
    HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    if (GetConsoleScreenBufferInfo( hStdOut, &csbi ))
    {
        csbi.dwCursorPosition.X = Clamp <SHORT> ( 0, csbi.dwCursorPosition.X+offset_X, csbi.dwSize.X-1 );
        csbi.dwCursorPosition.Y = Clamp <SHORT> ( 0, csbi.dwCursorPosition.Y+offset_Y, csbi.dwSize.Y-1 ); 
        SetConsoleCursorPosition( hStdOut, csbi.dwCursorPosition );
    }
}

(I typed this in off the top of my head. Hopefully I got it right.)

Now, you can move the cursor relative to its current position easily enough:
1
2
3
4
        case 72: if (current_keys.Up_Arrow)    Move_Cursor_Relative( 0, -Skipper ); break;
        case 80: if (current_keys.Down_Arrow)  Move_Cursor_Relative( 0,  Skipper ); break;
        case 75: if (current_keys.Left_Arrow)  Move_Cursor_Relative( -Skipper, 0 ); break;
        case 77: if (current_keys.Right_Arrow) Move_Cursor_Relative(  Skipper, 0 ); break;

Oh, be careful with your global variables' names.

Hope this helps.
Jul 28, 2016 at 1:55pm
Once again you come and help me Duoas :)
sadly i didn't learn templates yet can you send me a good source to learn templates and what is "Clamp" and what does this do:
csbi.dwCursorPosition.X = Clamp <SHORT> ( 0, csbi.dwCursorPosition.X+offset_X, csbi.dwSize.X-1 );
csbi.dwCursorPosition.Y = Clamp <SHORT> ( 0, csbi.dwCursorPosition.Y+offset_Y, csbi.dwSize.Y-1 );

and an explanation on how to use your template,Move_Cursor_Relative and how do i access the switch case and where ? i didn't quite understand how your code works and hope its not too much to ask.
Jul 28, 2016 at 4:49pm
Sorry. Simpler version:
1
2
3
4
int Clamp( int minimum, int value, int maximum )
{
  return std::max( minimum, std::min( value, maximum ) );
}

It returns value such that minimum ≤ value ≤ maximum.


The code I gave you does exactly what your code does:
- I removed the two variables previously indicated (you don't need them).
- I renamed "set" to the more descriptive "current_keys".

Everything else will require you to try it out and see it work.

Good luck!
Jul 29, 2016 at 8:56am
thanks! i will play around with your code and adapt it.
Topic archived. No new replies allowed.