newpad() 建立超出螢幕大小的虛擬螢幕,配合 prefresh() 實現捲動效果。
#include
#include
int main() {
setlocale(LC_ALL, "");
int y, x, i, j, h, w;
WINDOW *pad;
initscr();
getmaxyx(stdscr, h, w); // 取得螢幕尺寸
// 畫棋盤背景
for (i = 0; i < h; i++)
for (j = 0; j < w; j++)
mvaddch(i, j, ACS_CKBOARD);
refresh();
// 建立 80x90 的 pad
pad = newpad(80, 90);
for (i = 0; i < 80; i++) {
char line[90];
sprintf(line, "line %d\n", i);
mvwprintw(pad, i, 1, line);
}
refresh();
// 顯示 pad 區域 (pad座標 0,1 到 螢幕 5,10-20,25)
prefresh(pad, 0, 1, 5, 10, 20, 25);
// 捲動動畫
for (i = 0; i < 65; i++) {
prefresh(pad, i + 1, 1, 5, 10, 20, 25);
usleep(30000); // 30ms 延遲
}
getch();
delwin(pad);
endwin();
return 0;
}

// wmove/wprintw: 視窗相對游標操作
wmove(win2, 1, 1); printw("WIN2");
// 批次刷新: wnoutrefresh + doupdate
wnoutrefresh(win2);
wnoutrefresh(subwin);
doupdate();
// getyx: 取得子視窗邏輯游標位置
getyx(subwin, y, x);
mvwprintw(subwin, y+1, x, "................");

menu.h)static const char *menus[] = {"1-1","1-2","1-3","2-1","2-2","2-3"};
#define CITEM sizeof(menus)/sizeof(menus[0])
ITEM *items[CITEM];
for (int i = 0; i < CITEM; i++)
items[i] = new_item(menus[i], menus[i]); // 第二參數為描述
MENU *mymenu = new_menu(items);
set_menu_format(mymenu, CITEM, 1); // CITEM 行 1 列
set_menu_mark(mymenu, ">"); // 選中標記
int mrows, mcols;
scale_menu(mymenu, &mrows, &mcols); // 取得選單尺寸
WINDOW *win = newwin(mrows+2, mcols+2, 3, 30);
keypad(win, TRUE);
box(win, 0, 0);
WINDOW *subwin = derwin(win, 0, 0, 1, 1);
set_menu_sub(mymenu, subwin);
post_menu(mymenu);
refresh(); wrefresh(win);
int ch;
while (toupper(ch = wgetch(win)) != '\n') {
if (ch == KEY_DOWN) menu_driver(mymenu, REQ_DOWN_ITEM);
else if (ch == KEY_RIGHT) menu_driver(mymenu, REQ_RIGHT_ITEM);
else if (ch == KEY_UP) menu_driver(mymenu, REQ_UP_ITEM);
else if (ch == KEY_LEFT) menu_driver(mymenu, REQ_LEFT_ITEM);
}
// 取得選中項目
mvprintw(LINES-2, 0, "you select: %s\n", item_name(current_item(mymenu)));
refresh();
unpost_menu(mymenu);
free_menu(mymenu);
for (int i = 0; i < CITEM; i++) free_item(items[i]);
endwin();
gcc -lncursesw -lmenu 2.c -o mytest
./mytest
