views:

407

answers:

5

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.

+4  A: 

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);
Dave18
`SetConsoleCursorPosition` is a Windows Console Function, which I stated that I would like to avoid using.
Jim Fell
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
+2  A: 

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
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
@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
@Jerry: Please see the addtional details that I've added to the question. Thanks.
Jim Fell
@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
Jerry, thanks for the suggestions. I ended up writing a wrapper class to handle all the console manipulation.
Jim Fell
A: 

If you are trying to simply move the cursor to the beginning of the line so that the next printf overwrites the current line, you can use printf("\r"). Otherwise, you will have to use a library or a platform specific API.

MSN
I would like to be able to move the cursor to any position on the screen by providing a set of {x,y} coordinates.
Jim Fell
+1  A: 

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

Mark Ransom
Hmmm, that's a possibility. Thanks.
Jim Fell
+3  A: 

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.

Hans Passant