Thread: Eeks! locating a the cursor in a console app is a real _bear().

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    9

    Eeks! locating a the cursor in a console app is a real _bear().

    I'm working on a custom keyboard input routine. Again, thanks for the help yesterday with _getch(). I now have a loop that assigns a key press to a variable and uses printf to print it to the screen if it is a standard writing character. I also used the FAQ to find how to trap the cursor arrow keys in C.

    When I type: 123 to the screen, I see...

    123_

    ...in the console. Now, here's the trick...how to tell the code in the SWITCH conditional statement for arrow key left that when I hit the left arrow key to move back one space, I will have:

    123

    displayed in the console?

    I have seen the gotoxy() example in the FAQ, but I cannot get it to LINK. It compiles but it gives the LINK error message:

    C:\DEV-C_~1\LIB\\libmingw32.a(main.o)(.text+0x8e): undefined reference to `WinMain@16'

    I must be missing something. I am using Dev-C++ version 4.0 and not the latest beta 5 (4.9.4.1) version.

    I have downloaded Win32API and I know that there is a console cursor routine that has a library I could use. (Sorry, long statement name and I cannot recall it now, but I can find it later.)

    Anyway, what would be the best way to keep the code as portable as possible and manipulate the cursor? Also, any ideas as to what I am missing that causes the gotoxy() sample in the FAQ not to link in my compiler?

    Thanks,

    Pete

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Anyway, what would be the best way to keep the code as portable as possible and manipulate the cursor? Also, any ideas as to what I am missing that causes the gotoxy() sample in the FAQ not to link in my compiler?
    The FAQ's gotoxy() uses <windows.h>. You might have to use WinMain() in that case.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    9

    Thanks, got it to link now.

    Code:
    #include <stdio.h>
    #include <wndows.h>
    
    int main(int argc, char *argv[])
    {
    
    void gotoxy(int x, int y)
    {
      COORD coord;
      coord.X = x;
      coord.Y = y;
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }
     _getch();
    
      return 0;
    }
    ------------------------------------------------------

    Could I please get an example of how to set x and y using this code so that the cursor position will be displayed at row 3 and column 2?

    Thanks,

    Pete

  4. #4
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can't put a function smack in the middle of another one. Put it outside main().
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Code:
    #include <stdio.h>
    #include <wndows.h>
    
    void gotoxy(int x, int y)
    {
      COORD coord;
      coord.X = x;
      coord.Y = y;
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }
    
    int main(int argc, char *argv[])
    {
    
    gotoxy(2, 3); // row 2, column 3
     _getch();
    
      return 0;
    }

  6. #6
    Registered User
    Join Date
    May 2006
    Posts
    9
    Thanks!

    And wow, this forum is fast. I will take a few days and work on my keyboard routine. I have all the statements and functions I need for now, so it's time to put it all together.

    Thanks again for all your help,

    Pete

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Presumably this is just a typo:
    Code:
    #include <wndows.h>
    ->
    Code:
    #include <windows.h>
    When I type: 123 to the screen, I see...

    123_

    ...in the console. Now, here's the trick...how to tell the code in the SWITCH conditional statement for arrow key left that when I hit the left arrow key to move back one space, I will have:

    123

    displayed in the console?
    You don't need gotoxy for this at all. You can detect a backspace pressed with getche(), print a '\r', your text, and a couple of '\b's.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    May 2006
    Posts
    9
    Actually, I do need gotoxy. Keyboard input routines that evolve into word-processors require the programmer has complete control of the cursor position. You don't want certain keys pressed to be printed to the screen at all. getche() will print ascii characters for many keys. That is what makes it unacceptable. Basic has a similar problem with LINE INPUT. It is a good statement in the fact that it excludes the keys with ascii values that are not standard written characters; however, it has many limits. You have to wait for Enter to be pressed, so you can not run other functions within a loop or assign certain keys as function keys. You have to wait for the input to be finished. It also can have up to four lines of input, which can cause problems with the screen appearance if less than four lines, as is commonly the case, is provided for input. In QuickBasic, INKEY$ solves for that and provides a way to assign a variable to a key but not display it. grtch in C works pretty much the same. In QuickBasic, the cursor position is manipulated with LOCATE [row, cloumn] gotoxy seems to be the C equivalent to LOCATE.

    Here are two that maybe you can help me with:

    In QuickBasic CSRLIN returns the current cursor position and POS returns the current cursor column. So, is there a way to get the information back from gotoxy to be able to see the value (row and column numbers) of the current cursor position?

    BTW - Making good progress. I'm able to print the text I want to the screen and move the cursor back and forth under the printed characters.

    Thanks,

    Pete

    P.S. And yes, that was a typo...'wndows.h'

  9. #9
    Dump Truck Internet valis's Avatar
    Join Date
    Jul 2005
    Posts
    357
    http://msdn.microsoft.com/library/en...asp?frame=true
    GetConsoleScreenBufferInfo gives more information than you want, but the CONSOLE_SCREEN_BUFFER_INFO struct does have the cursor's position.

  10. #10
    Registered User
    Join Date
    May 2006
    Posts
    9
    Thanks Valis,

    I tried a couple of times to work with it but kept getting parsing errors. The link will come in handy. I need to learn some more C structure to work with these libraries.

    I may just keep track of the cursor position simply by adding or subtracting to the row and column with cursor changes and printing. That is fairly simple to do. I will eventually have to learn to read from the screen so I can copy the screen contents and save the color and characters in an array. That allows for the screen characters and color to be replaced when a popup is placed on the screen such as a drop-down menu or an alert box.

    Fun stuff,

    Pete

  11. #11
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I tried a couple of times to work with it but kept getting parsing errors.
    You always get this if you don't include <windows.h>.

    I will eventually have to learn to read from the screen so I can copy the screen contents and save the color and characters in an array. That allows for the screen characters and color to be replaced when a popup is placed on the screen such as a drop-down menu or an alert box.
    You could just have an array
    Code:
    unsigned char screen[80][25];
    that holds one screen, and when it's time to re-draw that screen, compare it with another screen to see what you need to repaint.

    There are lots of functions in <conio.h>, including ones to change the cursor's colour and get the cursor position and change the cursor type (_setcursortype(), _NOCURSOR, _BLOCKCURSOR, and _NORMALCURSOR). Have a look around in there.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  12. #12
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    is there any equivalent function

    void getxy( int &x, int &y );

    ?? Just out of curiosity that is.

    Cheers

  13. #13
    Registered User
    Join Date
    May 2006
    Posts
    34
    Here's some code I used to get the x and y position of the cursor...you can combine 'em into one function if you need:

    Code:
    short CConsole::WhereX()
    {
    	CONSOLE_SCREEN_BUFFER_INFO csbi;
    	GetConsoleScreenBufferInfo(stdOut, &csbi);
    	return csbi.dwCursorPosition.X;
    }
    
    
    short CConsole::WhereY()
    {
    	CONSOLE_SCREEN_BUFFER_INFO csbi;
    	GetConsoleScreenBufferInfo(stdOut, &csbi);
    	return csbi.dwCursorPosition.Y;
    }
    The stdOut var used in those functions is defined as:

    HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. %16 with double
    By spank in forum C Programming
    Replies: 11
    Last Post: 03-05-2006, 10:10 PM
  2. Graphics in the console (for real)
    By harryP in forum C++ Programming
    Replies: 11
    Last Post: 10-16-2003, 04:54 PM
  3. Programming Puns
    By kermi3 in forum A Brief History of Cprogramming.com
    Replies: 44
    Last Post: 03-23-2002, 04:38 PM
  4. Is it possible to get a console up with a win32 app?
    By SilentStrike in forum Windows Programming
    Replies: 2
    Last Post: 12-18-2001, 05:15 PM
  5. Turning a Console APP into Windows.
    By Darkflame in forum C++ Programming
    Replies: 3
    Last Post: 09-14-2001, 03:10 AM