manipulating the cursor position.

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;

	}
}
closed account (48bpfSEw)
 
void Navigation(short Skipper, short CoordX, short CoordY)


the parameters are passed by value and not by reference : &CoordX, &CoordY
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
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.
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.
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!
thanks! i will play around with your code and adapt it.
Topic archived. No new replies allowed.