Setting the Cursor Position in a Win32 Console Application
Asked Answered
S

5

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.

Schoolbook answered 28/4, 2010 at 18:52 Comment(1)
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?Melantha
S
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);
Separable answered 28/4, 2010 at 18:57 Comment(2)
SetConsoleCursorPosition is a Windows Console Function, which I stated that I would like to avoid using.Schoolbook
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!Schoolbook
D
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);
}
Danndanna answered 28/4, 2010 at 18:58 Comment(5)
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.Schoolbook
@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.Danndanna
Please see the addtional details that I've added to the question. Thanks.Schoolbook
@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.Danndanna
Jerry, thanks for the suggestions. I ended up writing a wrapper class to handle all the console manipulation.Schoolbook
S
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);
Separable answered 28/4, 2010 at 18:57 Comment(2)
SetConsoleCursorPosition is a Windows Console Function, which I stated that I would like to avoid using.Schoolbook
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!Schoolbook
G
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.

Granicus answered 29/4, 2010 at 0:49 Comment(0)
M
1

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

Maymaya answered 28/4, 2010 at 22:50 Comment(1)
Hmmm, that's a possibility. Thanks.Schoolbook
T
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;
}
Traceytrachea answered 27/1, 2015 at 18:17 Comment(2)
Need more information. There is no method called SetCursorPos.Erdmann
@GavinWilliams Method was present in win 7 don't know about win 10Traceytrachea

© 2022 - 2024 — McMap. All rights reserved.