20

How can I set the cursor position in a Win32 Console application? Preferably, I would like to avoid making a handle and using the Windows Console Functions. (I spent all morning running down that dark alley; it creates more problems than it solves.) I seem to recall doing this relatively simply when I was in college using stdio, but I can't find any examples of how to do it now. Any thoughts or suggestions would be greatly appreciated. Thanks.

Additional Details

Here is what I am now trying to do:

COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL );
char * str = "Some Text\r\n";
DWDORD len = strlen(str);

SetConsoleCursorPosition(hConsole_c, pos);
WriteConsole(hConsole_c, str, len, &dwBytesWritten, NULL);
CloseHandle(hConsole_c)

The text string str is never sent to the screen. Is there something else that I should be doing? Thanks.

Jim Fell
  • 13,750
  • 36
  • 127
  • 202
  • Good question, which is why I'm in this post, this was so easy to do in Turbo Pascal on pre-graphics card PCs (XT, AT and 386) even as a high school student, as a final assignment, I was able to create an interface to enter details into a fictitious ticket booking system... and got an A+, why is it so difficult now? – Michael Stimson Nov 08 '18 at 01:10

5 Answers5

17

Using the console functions, you'd use SetConsoleCursorPosition. Without them (or at least not using them directly), you could use something like gotoxy in the ncurses library.

Edit: a wrapper for it is pretty trivial:

// Untested, but simple enough it should at least be close to reality...
void gotoxy(int x, int y) { 
    COORD pos = {x, y};
    HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(output, pos);
}
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • The `gotoxy` is what I had in mind, but I found that even though the `SetConsoleCursorPosition` API does correctly set the cursor position, when I attempt to send text to the console using `printf`, the text is output to the location the cursor was at prior to calling the API. – Jim Fell Apr 28 '10 at 19:06
  • @Jim: It would be interesting to know what compiler does that. I've used code like this with Microsoft's compiler for years, and never seen the behavior you describe. – Jerry Coffin Apr 28 '10 at 19:34
  • Please see the addtional details that I've added to the question. Thanks. – Jim Fell Apr 28 '10 at 21:16
  • @Jim: you're creating and writing to a screen buffer (basically just a block of memory), but not writing to the console itself, or associating the screen buffer you created with the console. – Jerry Coffin Apr 28 '10 at 21:40
  • Jerry, thanks for the suggestions. I ended up writing a wrapper class to handle all the console manipulation. – Jim Fell Apr 29 '10 at 14:05
15

See SetConsoleCursorPosition API

Edit:

Use WriteConsoleOutputCharacter() which takes the handle to your active buffer in console and also lets you set its position.

int x = 5; int y = 6;
COORD pos = {x, y};
HANDLE hConsole_c = CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole_c);
char *str = "Some Text\r\n";
DWORD len = strlen(str);
DWORD dwBytesWritten = 0;
WriteConsoleOutputCharacter(hConsole_c, str, len, pos, &dwBytesWritten);
CloseHandle(hConsole_c);
cpx
  • 17,009
  • 20
  • 87
  • 142
  • `SetConsoleCursorPosition` is a Windows Console Function, which I stated that I would like to avoid using. – Jim Fell Apr 28 '10 at 19:08
  • So, I ended up going with Hans suggestion of using `GetStdHandle(STD_OUTPUT_HANDLE)` to get the handle to the existing console, but it turned out that I needed to use `WriteConsoleOutputCharacter()` as well. I don't know why that call does the trick, but it's working now. Thanks! – Jim Fell Apr 29 '10 at 14:03
4

Yeah, you forgot to call SetConsoleActiveScreenBuffer. What exactly was the point of creating your own? Use GetStdHandle(STD_OUTPUT_HANDLE) to get a handle to the existing console.

MD XF
  • 7,860
  • 7
  • 40
  • 71
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

You were probably using ANSI excape code sequences, which do not work with Windows 32-bit console applications.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1
#include <windows.h>
#include <iostream.h>
using namespace std;
int main(int argc, char *argv[])
{
  int x,y;
  cin>>x>>y;
  SetCursorPos(x,y); //set your co-ordinate
  Sleep(500);
  mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0); // moving cursor leftdown
  mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0); // moving cursor leftup //for accessing your required co-ordinate
  system("pause");
  return EXIT_SUCCESS;
}
udit043
  • 1,610
  • 3
  • 22
  • 40