Search code examples
c++windowncurses

Cannot write to an ncurses window using mvwprintw()


For days I'm trying to figure out the reason for the problem I have with this code:

#include <ncurses.h>
#include <stdlib.h>
#include<iostream>
using namespace std;

WINDOW *create_newwin(int height, int width, int starty, int startx);
void destroy_win(WINDOW *local_win);

int main(int argc, char *argv[]) {  
    WINDOW *my_win;
    int startx, starty, width, height;
    int ch;

    initscr();              // Start curses mode        
    // cbreak();            // Line buffering en/disabled, pass on
                            // everything to me         
    keypad(stdscr, TRUE);   // I need that nifty F2

    height = 3;
    width = 10;
    starty = (LINES - height) / 2;  /* Calculating for a center placement */
    startx = (COLS - width) / 2;    /* of the window        */
    printw("Press F2 to exit!\n");
    refresh();
    my_win = create_newwin(height, width, starty, startx);

    // keypad(my_win, TRUE);

    while((ch = getch()) != KEY_F(2))   {   
        switch(ch) {    
            case KEY_LEFT:
                destroy_win(my_win);
                my_win = create_newwin(height, width, starty,--startx);
                break;
            case KEY_RIGHT:
                destroy_win(my_win);
                my_win = create_newwin(height, width, starty,++startx);
                break;
            case KEY_UP:
                destroy_win(my_win);
                my_win = create_newwin(height, width, --starty,startx);
                break;
            case KEY_DOWN:
                destroy_win(my_win);
                my_win = create_newwin(height, width, ++starty,startx);
                break;
            case 49:
                // Kann nicht in das Fenster my_win ausgeben, Fkt.
                // wird ignoriert:
                mvwprintw(my_win, 1, 1, "Value: %d, H %d, W %d, STy %d, STx %d", 1, height, width, starty, startx);
                cout << "   cout -> Values: height " <<  height  << ", width "<< width <<  ", starty " << starty <<  ", startx " << startx << endl;
                break;  
        }
    }
        
    endwin();           /* End curses mode */
    return 0;
}

WINDOW *create_newwin(int height, int width, int starty, int startx) {  
    WINDOW *local_win;

    local_win = newwin(height, width, starty, startx);
    box(local_win, 0 , 0);      // 0, 0 gives default characters 
                                // for the vertical and horizontal
                                // lines.
    wrefresh(local_win);        // Show that box.

    return local_win;
}

void destroy_win(WINDOW *local_win) {
    /* box(local_win, ' ', ' '); : This won't produce the desired
     * result of erasing the window. It will leave it's four corners 
     * and so an ugly remnant of window. 
     */
    wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' ');
    /* The parameters taken are 
     * 1. win: the window on which to operate
     * 2. ls: character to be used for the left side of the window 
     * 3. rs: character to be used for the right side of the window 
     * 4. ts: character to be used for the top side of the window 
     * 5. bs: character to be used for the bottom side of the window 
     * 6. tl: character to be used for the top left corner of the window 
     * 7. tr: character to be used for the top right corner of the window 
     * 8. bl: character to be used for the bottom left corner of the window 
     * 9. br: character to be used for the bottom right corner of the window
     */
    wrefresh(local_win);
    delwin(local_win);
}

I took this from: https://tldp.org/HOWTO/NCURSES-Programming-HOWTO/windows.html.

Everything works as it should, with one exception:

In the case statement case 49: which I added, I try to print in the window my_win, but the function call is ignored. It has no effect. Instead, the pressed key "1" is printed on the stdscr. The cout line is just for debugging purposes and is also printed at the current cursor position in stdscr.

Any ideas what I'm doing wrong here? Or how to correct my possibly wrong understanding of the code?

Thanks beforehand to everyone!

Cheers!


Solution

  • After the definition of a correct initializing sequence which goes like

        initscr();
        cbreak();
        noecho();   
        intrflush(stdscr, FALSE);
        keypad(stdscr, TRUE);   // To receive F2
    

    I found out, that the most important thing I did not recognize all the time was a wrefresh(my_win); right after the mvwprintw line. So, also these print commands need a refresh of the pertinent window, otherwise the change is done but will not appear on screen.