Thread: Getch behaves as key is previous key.

  1. #1
    Registered User
    Join Date
    Mar 2011
    Location
    Stockholm, Sweden
    Posts
    20

    Getch behaves as key is previous key.

    I Wrote a little text-viewer for linux (using curses) this morning, but my problem is that it seems to belive that the key I feed getch() with was the previous key.
    For now- I just have keys for scrolling upp and down

    So - when I scroll down 10 lies, and then I scroll up 1 line - it scroll down one line more before it begins to scroll up. The same in the other direction.

    please be kind to me, this is the first program I have written in 10 years - and i wa sn't even a good programmer back then.

    Of course I have read a file to the strings and done proper errorchecking while
    open the file etcetera....before I come here. I just moved the variable definations
    from top of main for you to see the picture.

    Code:
          char rgsz[500+1][160+1]; //Array of strings which contains up to the 500 first
                                                     //Lines from the file.
    	int n_sz;                           //How many lines contains the array of strings.
    	int w_top=0,  w_bot=LINES; //Window Top and Bottom.
    	int key;                             //For getch()
    	bool f_upd_w=TRUE;        //Flag for Updating the Window
    	i=0;                                
    
             while (key != 27 ) {
            	key=getch();
    		if (f_upd_w == TRUE){
    			for ( i=w_top; i<w_bot-1; i++ ){
    				if ( (i <= 0) || (i >= n_sz  ) ){
    					break;
    				}
    				if (i < n_sz){
    					if (strlen (rgsz[ i ]) > COLS) { //Not yet implantated, needs
    						 w_bot--;                       //more work
    					}
    					printw("%d, %d, %d, %s",i, w_top, w_bot, rgsz[ i ]); 
    				}
    			        f_upd_w=FALSE;
    			}
    		}
    		switch (key){
    		case KEY_DOWN:
    		      if ( w_bot <= n_sz ){
    		         w_top++;
    		         w_bot++;
    		          f_upd_w=TRUE;
    		       }
    		break;
    		case KEY_UP:
    			w_top--;
    			w_bot--;
    			f_upd_w=TRUE;
    		break;
    		}
    	}

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I think it's the way you have your loop set. If I'm understanding you right, this is basically what you do:
    Code:
    loop
        read key
        draw window
        see what key we read
    Thus: >(1) >(2) <(3) gives you:
    read key (1)
    draw window without actually moving (0)
    process key (move window) (1)
    read key (2)
    draw window move from last time (1)
    process key (2)
    read key (3)
    draw window from (2)
    process key (3)

    Now you never draw your window from key (3).


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Location
    Stockholm, Sweden
    Posts
    20

    Arrow

    Quote Originally Posted by quzah View Post
    I think it's the way you have your loop set. If I'm understanding you right, this is basically what you do:
    Code:
    loop
        read key
        draw window
        see what key we read
    Thus: >(1) >(2) <(3) gives you:
    read key (1)
    draw window without actually moving (0)
    process key (move window) (1)
    read key (2)
    draw window move from last time (1)
    process key (2)
    read key (3)
    draw window from (2)
    process key (3)

    Now you never draw your window from key (3).
    Quzah.
    Oddly enough the window is updated for every time i scroll down one line, but i tried as you suggested with adding
    Code:
    			printw("%d, %d, %d, %s",i, w_top, w_bot, rgsz[ i ]); 
    		}
    	        f_upd_w=FALSE;
                    refresh(); //Refresh Just added
    	}
    }
    Which made the scrolling _less_ smothly.

    The problem with getch() reminds - which opposite to what I misstyped before is for n lines, not for 10 lines.

    To be a little more specific..
    When I Scroll n Lines, lets say I scroll down 3 Lines. Then I hit the KEY_UP button, the program scroll down one more line before it begin to scroll up.
    Last edited by #define whatevr; 03-13-2011 at 04:41 AM. Reason: remove typo

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Some keys generate two values when they are pressed. The arrow keys are among them.

    Since you're using ncurses, you should be able to run a program like this, by just replacing the <conio.h> with your ncurses header file.

    Note in this program, how it gets TWO values, if they are present, and not just one.

    Code:
    #include <stdio.h>
    #include <conio.h>
    
    #define ESC 27
    #define F1 59
    #define F2 60
    #define F3 61
    #define F4 62
    #define F5 63
    #define F6 64
    #define F7 65
    #define F8 66
    #define F9 67
    #define F10 68
    #define HOME 71
    #define UP 72
    #define PAGE_UP 73
    #define LEFT 75
    #define RIGHT 77
    #define END 79
    #define DOWN 80
    #define PAGE_DOWN 81
    
    int main(void) {
    
      char key;
      char msg[20];
      printf("\n\n\t\t\t     press escape to quit\n\n") ;
      do {
        key = getch();
        if (key == 0) {
          key = getch(); //key code has two keys - read the second one
          switch (key) {
            case F1: memcpy(msg,"F1", sizeof(msg)); break;
            case F2: memcpy(msg,"F2", sizeof(msg)); break;
            case F3: memcpy(msg,"F3", sizeof(msg)); break;
            case F4: memcpy(msg,"F4", sizeof(msg)); break;
            case F5: memcpy(msg,"F5", sizeof(msg)); break;
            case F6: memcpy(msg,"F6", sizeof(msg)); break;
            case F7: memcpy(msg,"F7", sizeof(msg)); break;
            case F8: memcpy(msg,"F8", sizeof(msg)); break;
            case F9: memcpy(msg,"F9", sizeof(msg)); break;
            case F10: memcpy(msg,"F10", sizeof(msg)); break;
            case PAGE_UP: memcpy(msg,"PAGE UP", sizeof(msg)); break;
            case PAGE_DOWN: memcpy(msg,"PAGE DOWN", sizeof(msg)); break;
            case HOME: memcpy(msg,"HOME", sizeof(msg)); break;
            case END: memcpy(msg,"END", sizeof(msg)); break;
            case UP: memcpy(msg,"UP", sizeof(msg)); break;
            case DOWN: memcpy(msg,"DOWN", sizeof(msg)); break;
            case LEFT: memcpy(msg,"LEFT", sizeof(msg)); break;
            case RIGHT: memcpy(msg,"RIGHT", sizeof(msg)); break;
            default:  memcpy(msg,"unknown key", sizeof(msg)); break;
          }
          printf("\n Key: %s", msg);
          continue;
        }
        if(key == ESC)
          printf("\n Key: ESCAPE");
        else 
          printf("\n Key: %c", key);
       
      }while (key != ESC); 
    
      printf("\n\n\t\t\t     press enter when ready");
      (void) getchar();  //hold the console window open
      return 0;
    }
    That will fix your problem, if you implement it into your program.

  5. #5
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    memcpy seems wrong.
    Your source does have that many to copy.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The memcpy() is peripheral, and not the point. The point is, some keys, when pressed, generate TWO not one, value, and if the key does generate two values, then the SECOND value is the one you want to work with, in this program.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Adak View Post
    The memcpy() is peripheral, and not the point. The point is, some keys, when pressed, generate TWO not one, value, and if the key does generate two values, then the SECOND value is the one you want to work with, in this program.
    Actually from your code, all he needs is the part you boldfaced, and the #defines...

    As you pointed out if he gets a 0 for a keypress he simply needs to look again...

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    What the hell do you think you're doing, understanding plain English, like this Tater?

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Adak View Post
    What the hell do you think you're doing, understanding plain English, like this Tater?
    I'm sorry... I don't get your meaning????

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Just a joke, Tater! Glad you got what I meant when I posted that code.

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Adak View Post
    Just a joke, Tater! Glad you got what I meant when I posted that code.
    Oh you were joking... I'm sorry, must have missed that ... perhaps if it was actually funny???

  12. #12
    Registered User
    Join Date
    Mar 2011
    Location
    Stockholm, Sweden
    Posts
    20
    I remember that in the dos and cpp days i did something like :

    Code:
    ch=getch();
      if (ch==0){
          ch=getch();
        do something
       }
       else{
       do something else
    }
    When i Look at the curses.h file the zero-keys are declared
    like this
    Code:
    ...
    #define KEY_DOWN	0402		/* down-arrow key */
    #define KEY_UP		0403		/* up-arrow key */
    #define KEY_LEFT	0404		/* left-arrow key */
    #define KEY_RIGHT	0405		/* right-arrow key */
    #define KEY_HOME	0406		/* home key */
    #define KEY_BACKSPACE	0407		/* backspace key */
    #define KEY_F0		0410		/* Function keys.  Space for 64 */
    #define KEY_F(n)	(KEY_F0+(n))	/* Value of function key n */
    #define KEY_DL		0510		/* delete-line key *
    ...
    /
    Which led me to the conclusion that I didn't need to take special care for the function keys.

    Well, just to be sure I tried that solution before I posted here, but as that didn't help I remove it again.

    I think the error is somewhere else in the while-loop.
    Last edited by #define whatevr; 03-13-2011 at 12:07 PM.

  13. #13
    Registered User
    Join Date
    Mar 2011
    Location
    Stockholm, Sweden
    Posts
    20
    I changed the PAGE_UP and PAGE_DOWN statements in the case to
    Code:
    case j:
    and
    Code:
    case k:
    to use the vi-style (uugh - hate it).

    The error is still the same..
    Last edited by #define whatevr; 03-13-2011 at 04:11 PM.

  14. #14
    Registered User
    Join Date
    Mar 2011
    Location
    Stockholm, Sweden
    Posts
    20
    Quote Originally Posted by #define whatevr View Post
    Oddly enough the window is updated for every time i scroll down one line, but i tried as you suggested with adding
    Code:
    			printw("%d, %d, %d, %s",i, w_top, w_bot, rgsz[ i ]); 
    		}
    	        f_upd_w=FALSE;
                    refresh(); //Refresh Just added
    	}
    }
    Which made the scrolling _less_ smothly.

    The problem with getch() reminds - which opposite to what I misstyped before is for n lines, not for 10 lines.

    To be a little more specific..
    When I Scroll n Lines, lets say I scroll down 3 Lines. Then I hit the KEY_UP button, the program scroll down one more line before it begin to scroll up.


    Ahh, now I got it.

    I moved the getch() command to below the if statement, which is containing the for( ; ; ) loop.
    Thank you for your help.

    Problem solved.
    Last edited by #define whatevr; 03-13-2011 at 04:17 PM. Reason: Smiley hijacking

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. "press any key to continue" without the enter key
    By chickenandfries in forum C Programming
    Replies: 1
    Last Post: 03-29-2008, 09:56 PM
  2. Window message loop (Keys)
    By Blackroot in forum Windows Programming
    Replies: 3
    Last Post: 09-12-2006, 05:15 PM
  3. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM