利用 Ncurses Panel 庫實現三個重疊窗口同時編輯,支持窗口切換(Tab)、鼠標定位、文件讀寫(F9/F10)、刪除行(F12)、退出確認(F11)等功能,展示面板管理的強大能力。
WINDOW *mywins[3];
PANEL *mypanels[3];
PANEL *top;
for (int i = 0; i < 3; ++i) {
mywins[i] = newwin(height, width, begin_y, begin_x);
keypad(mywins[i], TRUE);
wattron(mywins[i], COLOR_PAIR(i+1));
mypanels[i] = new_panel(mywins[i]); // 關聯窗口創建面板
box(mywins[i], ACS_VLINE, ACS_HLINE);
wattroff(mywins[i], COLOR_PAIR(i+1));
begin_y += 4; begin_x += 4; // 錯開位置形成層疊效果
}
// 設置面板用戶指針實現循環切換
set_panel_userptr(mypanels[0], mypanels[1]);
set_panel_userptr(mypanels[1], mypanels[2]);
set_panel_userptr(mypanels[2], mypanels[0]);
top = mypanels[2]; // 初始頂層面板
update_panels();
doupdate();
核心邏輯:針對當前頂層面板 nowwinid 處理輸入,支持鍵盤導航、鼠標點擊定位、功能鍵操作:
while (1) {
int c = mvwgetch(mywins[nowwinid], y, x);
switch (c) {
case KEY_MOUSE: // 鼠標事件
if (getmouse(&event) == OK && (event.bstate & BUTTON1_PRESSED)) {
y = event.y - 7; x = event.x - 7;
wmove(mywins[nowwinid], y, x);
}
break;
case KEY_BACKSPACE: // 退格刪除
--x; if (x < 1) { --y; x = width-2; }
if (y < 1) y = height-2;
mvwprintw(mywins[nowwinid], y, x, " ");
break;
case KEY_F(11): // F11 退出確認
// ... 彈出確認對話框,處理用戶輸入 ...
break;
case 9: // Tab 鍵切換窗口
top = (PANEL *)panel_userptr(top);
nowwinid = (nowwinid + 1) % 3;
// 更新文件名等上下文
break;
// ... 其他方向鍵、Enter、F9讀取、F10保存、F12刪除行等 ...
}
update_panels();
doupdate();
}
myed{N}.dat,逐字符讀入窗口update_panels() 計算遮擋關係,doupdate() 一次性刷新物理屏幕set_panel_userptr 串聯面板,實現 Tab 循環切換頂層窗口mousemask(ALL_MOUSE_EVENTS, &oldmask) 啟用鼠標,getmouse 解析坐標啟動後顯示三個不同顏色邊框的重疊窗口,按 Tab 切換活動窗口,支持滑鼠點擊定位光標,功能鍵操作獨立作用於當前窗口。

Panel 庫將窗口管理抽象為棧結構,極大簡化了多窗口遮擋、刷新、切換的複雜度。結合鼠標與鍵盤事件,可構建媲美圖形界面的終端應用。