⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch16.htm

📁 ncurses中文说明
💻 HTM
📖 第 1 页 / 共 2 页
字号:
	{	switch(ch)
		{	case 9:				/* Tab 对应编号 */
				top = (PANEL_DATA *)panel_userptr(stack_top);
				top_panel(top->next);
				stack_top = top->next;
				top = (PANEL_DATA *)panel_userptr(stack_top);
				newx = top->x;
				newy = top->y;
				neww = top->w;
				newh = top->h;
				break;
			case 'r':				/* 改变大小*/
				size = TRUE;
				attron(COLOR_PAIR(4));
				mvprintw(LINES - 4, 0, "Entered Resizing :Use Arrow Keys to resize and press <ENTER> to end resizing");
				refresh();
				attroff(COLOR_PAIR(4));
				break;
			case 'm':				/* 移动 */
				attron(COLOR_PAIR(4));
				mvprintw(LINES - 4, 0, "Entered Moving: Use Arrow Keys to Move and press <ENTER> to end moving");
				refresh();
				attroff(COLOR_PAIR(4));
				move = TRUE;
				break;
			case KEY_LEFT:
				if(size == TRUE)
				{	--newx;
					++neww;
				}
				if(move == TRUE)
					--newx;
				break;
			case KEY_RIGHT:
				if(size == TRUE)
				{	++newx;
					--neww;
				}
				if(move == TRUE)
					++newx;
				break;
			case KEY_UP:
				if(size == TRUE)
				{	--newy;
					++newh;
				}
				if(move == TRUE)
					--newy;
				break;
			case KEY_DOWN:
				if(size == TRUE)
				{	++newy;
					--newh;
				}
				if(move == TRUE)
					++newy;
				break;
			case 10:				/* Enter对应编号 */
				move(LINES - 4, 0);
				clrtoeol();
				refresh();
				if(size == TRUE)
				{	old_win = panel_window(stack_top);
					temp_win = newwin(newh, neww, newy, newx);
					replace_panel(stack_top, temp_win);
					win_show(temp_win, top->label, top->label_color); 
					delwin(old_win);
					size = FALSE;
				}
				if(move == TRUE)
				{	move_panel(stack_top, newy, newx);
					move = FALSE;
				}
				break;
			
		}
		attron(COLOR_PAIR(4));
		mvprintw(LINES - 3, 0, "Use 'm' for moving, 'r' for resizing");
	    mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F1 to Exit)");
	    	attroff(COLOR_PAIR(4));
	        refresh();	
		update_panels();
		doupdate();
	}
	endwin();
	return 0;
}

/* 显示所有的窗口 */
void init_wins(WINDOW **wins, int n)
{	int x, y, i;
	char label[80];

	y = 2;
	x = 10;
	for(i = 0; i < n; ++i)
	{	wins[i] = newwin(NLINES, NCOLS, y, x);
		sprintf(label, "Window Number %d", i + 1);
		win_show(wins[i], label, i + 1);
		y += 3;
		x += 7;
	}
}

/* 把每个面板设置为 PANEL_DATA 结构 */
void set_user_ptrs(PANEL **panels, int n)
{	PANEL_DATA *ptrs;
	WINDOW *win;
	int x, y, w, h, i;
	char temp[80];
	
	ptrs = (PANEL_DATA *)calloc(n, sizeof(PANEL_DATA));

	for(i = 0;i < n; ++i)
	{	win = panel_window(panels[i]);
		getbegyx(win, y, x);
		getmaxyx(win, h, w);
		ptrs[i].x = x;
		ptrs[i].y = y;
		ptrs[i].w = w;
		ptrs[i].h = h;
		sprintf(temp, "Window Number %d", i + 1);
		strcpy(ptrs[i].label, temp);
		ptrs[i].label_color = i + 1;
		if(i + 1 == n)
			ptrs[i].next = panels[0];
		else
			ptrs[i].next = panels[i + 1];
		set_panel_userptr(panels[i], &ptrs[i]);
	}
}
/* 用一个边框和标题栏来显示窗口 */
void win_show(WINDOW *win, char *label, int label_color)
{	int startx, starty, height, width;

	getbegyx(win, starty, startx);
	getmaxyx(win, height, width);

	box(win, 0, 0);
	mvwaddch(win, 2, 0, ACS_LTEE); 
	mvwhline(win, 2, 1, ACS_HLINE, width - 2); 
	mvwaddch(win, 2, width - 1, ACS_RTEE); 
	
	print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
{	int length, x, y;
	float temp;

	if(win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if(startx != 0)
		x = startx;
	if(starty != 0)
		y = starty;
	if(width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length)/ 2;
	x = startx + (int)temp;
	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win, color);
	refresh();
}

</pre>
</font>
<p>
<dd>
我们把注意力集中在主循环上。一旦程序捕获某个键被按下,它就执行相应的动作。如果按下了‘r’键,“更改大小”模式就启动了。用户可以通过按方向键来更改面板的大小。当用户按<ENTER>键时,就确定了面板的新尺寸,程序就依照上面介绍的方法更改大小。不过在“更改大小”模式中,程序并没有真正显示出面板更改大小后的边框。这就留给读者一个作业:用点来显示新尺寸面板的边框。
</dd>
</p>
<p>
<dd>
当用户按‘m’键时“移动面板”模式就启动了。这个操作会比“更改大小”简单一点。随着方向键的按下,新面板的位置也随之移动,当<ENTER>键按下时,程序就调用panel()函数把面板移动到光标的当前位置。
</dd>
</p>
<p>
<dd>
在这个示范程序中,用户数据就代表PANEL_DATA,在查找面板的相关信息时扮演重要角色。就象在说明中所写,PANEL_DATA保存了面板的尺寸,标题,标题颜色和循环中指向下一个面板的指针。
</dd>
</p>
<br>
<br>
<h3 align="left">
<a name="hide">
16.6 隐藏和显示面板
</a>
</h3>
<br>
<p>
<dd>
隐藏一个面板可以使用函数hide_panel()。这个函数仅仅是把它从面板栈中移走,因此,要在屏幕上隐藏的话只要调用函数update_panels() 和 doupdate()就可以了。它不会破坏面板结构和这个隐藏的面板。函数show_panel()可以让它重新显示。
</dd>
</p>
<p>
<dd>
下面的程序显示了如何隐藏面板。按键 ’a’ 或 ’b’ 或 ‘c’来分别实现显示或隐藏第一,二,三个窗口,其它的依此类推。它使用了一个用户给定的一个带有隐藏的变量的数据,用来跟踪窗口是否是隐藏的。因为某些原因,按理用来告诉用户一个面板是否隐藏的函数panel_hidden没有起作用。Michael Andres 在这里提供了一个错误报告。
</dd>
</p>
<p>
例17、 一个隐藏和显示面板的例子
</p>
<font color="Maroon">
<pre>
#include &lt;panel.h&gt;

typedef struct _PANEL_DATA {
	int hide;						/* 如果面板是隐藏的时候为真  */
}PANEL_DATA;

#define NLINES 10
#define NCOLS 40

void init_wins(WINDOW **wins, int n);
void win_show(WINDOW *win, char *label, int label_color);
void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);

int main()
{	WINDOW *my_wins[3];
	PANEL  *my_panels[3];
	PANEL_DATA panel_datas[3];
	PANEL_DATA *temp;
	int ch;

	/* 初始化curses */
	initscr();
	start_color();
	cbreak();
	noecho();
	keypad(stdscr, TRUE);

	/* 初始化所有的颜色 */
	init_pair(1, COLOR_RED, COLOR_BLACK);
	init_pair(2, COLOR_GREEN, COLOR_BLACK);
	init_pair(3, COLOR_BLUE, COLOR_BLACK);
	init_pair(4, COLOR_CYAN, COLOR_BLACK);

	init_wins(my_wins, 3);
	
	/* 更新面板栈的顺序。把面板2置于栈顶 */
	my_panels[0] = new_panel(my_wins[0]); 	/* Push 0, order: stdscr-0 */
	my_panels[1] = new_panel(my_wins[1]); 	/* Push 1, order: stdscr-0-1 */
	my_panels[2] = new_panel(my_wins[2]); 	/* Push 2, order: stdscr-0-1-2 */

	/* 初始化所有的面板并都设为非隐藏的 */
	panel_datas[0].hide = FALSE;
	panel_datas[1].hide = FALSE;
	panel_datas[2].hide = FALSE;

	set_panel_userptr(my_panels[0], &panel_datas[0]);
	set_panel_userptr(my_panels[1], &panel_datas[1]);
	set_panel_userptr(my_panels[2], &panel_datas[2]);

	/* 更新面板栈的顺序,第二个面板将置于栈顶 */
	update_panels();

	/* 在屏幕上显示 */
	attron(COLOR_PAIR(4));
	mvprintw(LINES - 3, 0, "Show or Hide a window with 'a'(first window)  'b'(Second Window)  'c'(Third Window)");
	mvprintw(LINES - 2, 0, "F1 to Exit");

	attroff(COLOR_PAIR(4));
	doupdate();
	
	while((ch = getch()) != KEY_F(1))
	{	switch(ch)
		{	case 'a':			
				temp = (PANEL_DATA *)panel_userptr(my_panels[0]);
				if(temp->hide == FALSE)
				{	hide_panel(my_panels[0]);
					temp->hide = TRUE;
				}
				else
				{	show_panel(my_panels[0]);
					temp->hide = FALSE;
				}
				break;
			case 'b':
				temp = (PANEL_DATA *)panel_userptr(my_panels[1]);
				if(temp->hide == FALSE)
				{	hide_panel(my_panels[1]);
					temp->hide = TRUE;
				}
				else
				{	show_panel(my_panels[1]);
					temp->hide = FALSE;
				}
				break;
			case 'c':
				temp = (PANEL_DATA *)panel_userptr(my_panels[2]);
				if(temp->hide == FALSE)
				{	hide_panel(my_panels[2]);
					temp->hide = TRUE;
				}
				else
				{	show_panel(my_panels[2]);
					temp->hide = FALSE;
				}
				break;
		}
		update_panels();
		doupdate();
	}
	endwin();
	return 0;
}

/* 显示所有窗口 */
void init_wins(WINDOW **wins, int n)
{	int x, y, i;
	char label[80];

	y = 2;
	x = 10;
	for(i = 0; i < n; ++i)
	{	wins[i] = newwin(NLINES, NCOLS, y, x);
		sprintf(label, "Window Number %d", i + 1);
		win_show(wins[i], label, i + 1);
		y += 3;
		x += 7;
	}
}

/* 通过边框和标题显示窗口 */
void win_show(WINDOW *win, char *label, int label_color)
{	int startx, starty, height, width;

	getbegyx(win, starty, startx);
	getmaxyx(win, height, width);

	box(win, 0, 0);
	mvwaddch(win, 2, 0, ACS_LTEE); 
	mvwhline(win, 2, 1, ACS_HLINE, width - 2); 
	mvwaddch(win, 2, width - 1, ACS_RTEE); 
	
	print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
}

void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
{	int length, x, y;
	float temp;

	if(win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if(startx != 0)
		x = startx;
	if(starty != 0)
		y = starty;
	if(width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length)/ 2;
	x = startx + (int)temp;
	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win, color);
	refresh();
}

</pre>
</font>
<br>
<br>
<h3 align="left">
<a name="panel">
16.7  panel_above()和panel_below()类函数
</a>
</h3>
<br>
<p>
<dd>
函数panel_above() 和 panel_below() 可以用来查看某一个面板的上面和下面的面板。如果函数的参变量为NULL,它们就分别返回一个指向最底层和最上层面板的指针。
</dd>
</p>
</font>
</div>
<br>
<br>
<div align="center"><a href="index.htm"><font size="5">
    <strong>
    回  目  录
    </strong>
  </font></a></div>
  <div align="right">
  <font size="5">
  <a href="ch15.htm">
  <strong>
  上 一 章
  </strong>
  </a>
  <a href="ch17.htm">
    <strong>
    下 一 章
	</strong>
	</a>
	</font>
	</div>
	<br>
<br>
<br>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -