Ncurses wrefresh 不显示 window 边框

Ncurses wrefresh not showing window borders

我正在使用 ncurses 试验一些 C++,在显示 window 边框时遇到问题,但在使用以下程序时遇到问题。

#include <cstdio>
#include <cstdlib>
#include <ncurses.h>

int main(int argc, char **argv)
{
    if(argc != 5)
    {
        printf("not enough arguments\n"); 
        exit(1); 
    }
    int height = atoi(argv[1]); 
    int width = atoi(argv[2]); 
    int y = atoi(argv[3]);
    int x = atoi(argv[4]); 

    initscr(); 
    WINDOW *win = newwin(height, width, y, x);  
    box(win, 0, 0); 
    wrefresh(win); 

    int py, px; 
    getparyx(win, py, px); 
    mvprintw(LINES-2, 0, "getparyx: (%d, %d)", py, px); 

    int by, bx; 
    getbegyx(win, by, bx); 
    mvprintw(LINES-1, 0, "getbegyx: (%d, %d)", by, bx); 


    getch(); 
    delwin(win); 
    endwin(); 
}

在上面的程序中,我使用 box 绘制边框并使用 wrefresh 刷新,但它没有显示任何内容。但是,我打印到 stdscr 的其他内容确实显示了。

但是在另一个程序中我能够使边框正常工作。

#include <ncurses.h>

int main() 
{
    const int height = 6, width = 8; 

    WINDOW *win; 
    int starty, startx; 
    int ch; 

    initscr(); 
    cbreak(); 
    noecho(); 
    keypad(stdscr, TRUE); 

    starty = (LINES - height) / 2; 
    startx = (COLS - width) / 2; 
    win = newwin(height, width, starty, startx); 
    box(win, 0, 0); 
    wrefresh(win); 

    while((ch = getch()) != KEY_F(1)) 
    {
        wborder(win, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '); 
        wrefresh(win); 
        delwin(win); 
        switch(ch) 
        {
            case KEY_UP: 
                win = newwin(height, width, --starty, startx);                 
                break; 
            case KEY_DOWN:
                win = newwin(height, width, ++starty, startx); 
                break; 
            case KEY_LEFT: 
                win = newwin(height, width, starty, --startx); 
                break; 
            case KEY_RIGHT:
                win = newwin(height, width, starty, ++startx); 
                break; 
        }
        move(starty + (height / 2) - 1, startx + (width / 2) - 1); 
        box(win, 0, 0); 
        wrefresh(win); 
    }

    delwin(win); 
    endwin(); 
}

问题是边框只出现在循环中。换句话说,在我按下按钮之前边框不会开始显示,这意味着初始 wrefresh 不起作用。

在做了一些研究后,我 this 线程建议在 initscr 之后(或至少在 wrefresh() 之前)调用 refresh,但这没有用。那么第一个程序中没有显示边框,我错过了什么?

对于我的测试,最初的 refresh() 肯定是缺失的。我检查了我写的一些旧代码,它确实调用 refresh() 作为 ncurses 初始化的一部分。将此添加到您的代码中使它对我有用。许多 curses 文档仍然局限于书籍,从未真正出现在网络上。

initscr();
refresh();          // <-- HERE

WINDOW *win = newwin( height, width, y, x );  
box( win, 0, 0 );
wrefresh(win);

我认为窗口模型在第一个 refresh() 被调用之后才完全初始化。但是我找不到任何关于确切为什么会这样的文档。

这个答案没有太多细节,抱歉......但我希望它能有所帮助。

手册页回答了问题:

initscr also causes the first call to refresh(3x) to clear the screen.

If the window is not a pad, and it has been moved or modified since the last call to wrefresh, wrefresh will be called before another character is read.

  • initscr(清除)和mvprintw调用更新stdscr,最后刷新 当你调用 getch 时。 stdscr 是一个 window,并且如 wrefresh 的讨论中所述,物理屏幕按照应用刷新的顺序更新(也就是说,它与另一个重叠 window,如果你想出现另一个window,你应该先刷新stdscr,以处理清除操作)。