中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
用curses写的通用菜单修改后的正确程序!
作者:未知 时间:2005-09-13 19:23 出处:ChinaUnix.net 责编:chinaitpower
              摘要:用curses写的通用菜单修改后的正确程序!

总看到有人发帖子问那个通用菜单程序中的几个错误不能编译的事,回去找了一下我修改后可以正常工作的程序,现贴出来,大家共享一下吧。
我的系统是scounix的。
编译  cc menu.c -o menu -lcurses
[code:1:d1e7766ace] /*****************************************************************
本程序需要借肋两个参数文件来实现: 
(1)、对菜单中每一项参数进行说明的文件(menu.def),它格式如下所述: 
!所属菜单代号!项顺序号!菜单项名称!外挂程序名称!下级菜单代号! 
说明: 
1、如菜单代号为"0",则表示此项属于主菜单; 
2、如外挂程序名称为"0",则表示此菜单项对应的过程在菜单程序内部或对应于一个子菜单; 
3、如下级菜单代号为"0",则表示此菜单项无下级子菜单; 
4、项顺序号同时可作为菜单热键使用。 
假如文件menu.def中有下面这一行: 
!0!3!格式化磁盘!format /dev/rfd0135ds18!0! 
它表示主菜单的第三项为格式化磁盘,它对应的执行过程为 format /dev/rfd0135ds18,本项无子菜单。 
如果用户想把自己编的实现查询功能程序XXX挂到本程序主菜单第4项上,则可在menu.def中增加下面 
这一行: 
!0!4!查询!XXX!0! 
(2)、对各菜单参数进行说明文件(menu.conf),其格式如下所述: 
!菜单代号!上一级菜单代号!边框标志!菜单宽度!菜单行数!菜单列数!起始横坐标!起始纵坐标! 
说明: 
1、边框标志为"0"表示无框,为"1"表示有边框; 
2、上级菜单代号为"-1",表示无上级菜单; 
3、如菜单代号为"0",表示主菜单。 
当用户对菜单显示样式不满意时,可通过调整此文件设计个性化的界面 
****************************************************************/
#include <curses.h> 
#include <stdlib.h>
#define ESC 27  
#define ENT 13  
#define REFRESH 12  
#define MAX_M 10 /* 菜单最大层数 */  

void initial(),nomlastpos(),revcurpos(),disponepage(),dispprevline();
void dispnextline(),domenu(),getmenuconf(),keycont();
void getitem(), get_m_conf(), get_m_item(),clearwin(),execprog();
/* 标识每一菜单项的结构 */
struct menu {
short menu_code; /* 所属菜单代号 */

short item_order; /* 项顺序号 */

char item[20]; /* 菜单项名称 */

char prog[80]; /* 本项菜单执行程序 */

short submenu_code; /* 下一级菜单编号 */

struct menu *next; /* 指向上一项的指针 */

struct menu *prev; /* 指向下一项的指针 */

} m_item,*head,*this,*new,*last,*scrpos,*lastscrpos,*begin,*lastbegin,*lastscr[MAX_M];
/* 标识每一菜单内容的结构 */
struct menuconf {
short menu_code; /* 菜单代号 */

short last_code; /* 上一级菜单代号 */

short bord_flag; /* 边框标志 0--无边框 1--有边框 **/

short m_wight; /* 菜单显示宽度 */

short m_lengh; /* 每一行项数 */

short m_col; /* 菜单列数 */

short m_bx; /* 菜单起始横坐标 */

short m_by; /* 菜单起始纵坐标 */

} m_conf;
WINDOW *menuwin, *boxwin, *curw, *lastw[MAX_M], *workwin;
long curpos, lastcurpos, lastscrcurpos, lastmenucur[MAX_M];
short menu_no = 0, wno = 0;

main()
{
initial();
getmenuconf(0); /* 取第0号菜单参数 */


/* 创建主窗口 */
menuwin=newwin(m_conf.m_lengh, m_conf.m_wight, m_conf.m_bx+1, m_conf.m_by+1);
curw=menuwin;
lastw[wno]=menuwin;

getitem(); /* 取当前菜单各项内容 */

domenu(head, 0);
endwin();
}
/* 取菜单各项参数函数 */
void getitem()
{
FILE *fp;
char buff[0x100];

/* 建边框窗口 */
boxwin=newwin(m_conf.m_lengh+2,m_conf.m_wight+2,m_conf.m_bx,m_conf.m_by);
keypad(curw, TRUE);
if (m_conf.bord_flag==1) {
box(boxwin, 0,0 );
wrefresh(boxwin);
}

head=NULL;
if ((fp = fopen("menu.def","r")) == NULL) {
printw( "\n不能打开菜单定义文件\n");
refresh();
endwin();
exit(-1);
}
while( fgets(buff, 0x100, fp)!=NULL) {
get_m_item(buff);

if (m_item.menu_code != menu_no)
continue;

new=(struct menu*)malloc(sizeof(struct menu));
if (head == NULL) {
last = head;
head = new;
}
else {
this->next = new;
last = this;
}
this = new;
this->menu_code=m_item.menu_code;
this->item_order=m_item.item_order;
strcpy(this->item,m_item.item);
strcpy(this->prog,m_item.prog);
this->submenu_code=m_item.submenu_code;
this->next=NULL;
this->prev = last;
}
fclose(fp);
}
/* 菜单处理函数 */
void domenu(curscrp, curp)
struct menu *curscrp;
int curp;
{
int i, x, y;
struct menu *mpos;
int  ch;

this = head;
disponepage(this);
curpos = curp;
scrpos = curscrp;
lastcurpos = lastscrcurpos = 0;
revcurpos();
for(;;) {
ch=wgetch(curw);
switch (ch) {
case ENT:
/* 有下一级菜单 */
if ((!strcmp(scrpos->prog, "0")) && (scrpos->submenu_code != 0)) {
lastbegin = begin->next;
getmenuconf(scrpos->submenu_code);
menu_no = scrpos->submenu_code;

wno++;
lastmenucur[wno]=curpos;
lastscr[wno] = scrpos;
lastw[wno]=curw;

workwin=newwin(m_conf.m_lengh,m_conf.m_wight,m_conf.m_bx+1,m_conf.m_by+1);
curw=workwin;
getitem();
domenu(head, 0);
}
/* 是内部函数 */
/* 是外部可执行程序 */
else {
endwin();
execprog();
}
break;
case ESC:
case 'q':
case 'Q':
case '0':
/* 无上级菜单 */
if (m_conf.last_code == -1) {
clearwin();
endwin();
exit(0);
}
/* 有上级菜单 */
else {
menu_no = m_conf.last_code;
clearwin();
getmenuconf(menu_no);
getitem();
touchwin(lastw[wno]);
curw=lastw[wno];
curpos = lastmenucur[wno];
scrpos = lastscr[wno];
wno--;
wrefresh(curw);
}
break;
case 'r':
case 'R':
case REFRESH: /* 重显屏幕 */

wrefresh(curscr);
break;
case KEY_RIGHT: /* 右光标键 */

if ( scrpos->next != NULL ) {
lastcurpos = curpos;
lastscrpos = scrpos;
scrpos=scrpos->next;
getyx(curw, x, y);
if((x==m_conf.m_lengh-1)&&(curpos%m_conf.m_col==m_conf.m_col-1)){
curpos-=(m_conf.m_col-1);
lastcurpos = curpos - 1;
/* 实现向上卷屏 */
wmove(curw, 0, 0);
wdeleteln(curw);
dispnextline("R");
}
else 
curpos++;
if ((curpos%m_conf.m_col == 0) && (m_conf.m_lengh == 1)) {
revcurpos();
break;
}
else {
nomlastpos();
revcurpos();
}
}
break;
case KEY_LEFT: /* 左光标键 */

if ( scrpos->prev != NULL ) {
lastcurpos = curpos;
lastscrpos = scrpos;
scrpos=scrpos->prev;
getyx(curw, x, y);
if ((x==0) && (curpos%m_conf.m_col ==0)) {
curpos+=m_conf.m_col-1;
lastcurpos = curpos + 1;
/* 实现向下卷屏 */
winsertln(curw);
dispprevline("L");
}
else 
curpos--;
if ((curpos%m_conf.m_col==m_conf.m_col-1)&&(m_conf.m_lengh==1)) {
revcurpos();
break;
}
else {
nomlastpos();
revcurpos();
}
}
break;
case KEY_UP: /* 上光标键 */

lastcurpos = curpos;
lastscrpos = scrpos;
mpos = scrpos;
for(i=0;i < m_conf.m_col;i++){
if ( mpos->prev != NULL ) mpos=mpos->prev;
else break;
}
if ( i==m_conf.m_col ) {
getyx(curw, x, y);
if (x==0) {
lastcurpos += m_conf.m_col;
/* 实现向下卷屏 */
winsertln(curw);
dispprevline("U");
}
else {
curpos-=m_conf.m_col;
}
scrpos = mpos;
if ( m_conf.m_lengh!=1)
nomlastpos();
revcurpos();
}
break;
case KEY_DOWN: /* 下光标键 */

lastcurpos = curpos;
lastscrpos = scrpos;
mpos = scrpos;
for(i=0;i < m_conf.m_col;i++){
if ( mpos->next != NULL )
mpos=mpos->next;
else 
break;
}
if ( i==m_conf.m_col ) {
getyx(curw, x, y);
if (x==m_conf.m_lengh-1) {
lastcurpos -= m_conf.m_col;
/* 实现向上卷屏 */
wmove(curw, 0, 0);
wdeleteln(curw);
dispnextline("D");
}
else 
curpos+=m_conf.m_col;
scrpos = mpos;
if ( m_conf.m_lengh!=1)
nomlastpos();
revcurpos();
}
break;
default:
beep();
break;
}
}
}
/* 反显当前项函数 */
void revcurpos()
{
wattrset(curw, A_STANDOUT);
wmove(curw, curpos/m_conf.m_col,  
    (curpos%m_conf.m_col)*m_conf.m_wight/m_conf.m_col+m_conf.m_col);
wprintw(curw, "%s", scrpos->item);
wattrset(curw, A_NORMAL);
wrefresh(boxwin);
}
/* 正常显示上一项函数 */
void nomlastpos() {
wmove(curw, lastcurpos/m_conf.m_col, (lastcurpos%m_conf.m_col)
    *m_conf.m_wight/m_conf.m_col+m_conf.m_col);
wprintw(curw, "%s", lastscrpos->item);
}
/* 显示一页函数 */
void disponepage(first)
struct menu *first;
{
short col, row;

begin=first; /* begin 为本页首指针 */
for(row=0; row<m_conf.m_lengh;row++){
for(col=0; col<m_conf.m_col;col++){
/* m_conf.m_wight/m_col为每一菜单项应占字符数*/
wmove(curw,row,col*m_conf.m_wight/m_conf.m_col+m_conf.m_col);
wprintw(curw, "%s", first->item);
wrefresh(curw);
last = first;
first = first->next;
if (first == NULL) {
break;
}
}
}
}
/* 显示上一行函数 */
void dispprevline(flag)
char flag[2]; /* L-左光标引起 U-上光标引起 */
{
struct menu *tmppos;
int tmpcurpos;

tmpcurpos = curpos;
tmppos = scrpos;
if ( flag[0] == 'U') {
while ( tmpcurpos % m_conf.m_col != 0) {
tmppos = tmppos->prev;
tmpcurpos--;
}
tmppos = tmppos->prev;
}
for (tmpcurpos = m_conf.m_col-1; tmpcurpos >= 0; tmpcurpos--) {
wmove(curw, 0, (tmpcurpos%m_conf.m_col)*m_conf.m_wight/m_conf.m_col+m_conf.m_col);
wprintw(curw, "%s", tmppos->item);
begin = tmppos; /*begin 为本页首指针*/
last = tmppos;
tmppos = tmppos->prev;
if (tmppos == NULL)
break;
}
wrefresh(curw);
}
/* 显示下一行函数 */
void dispnextline(flag)
char flag[2];/* R-右光标引起 D-下光标引起 */
{
struct menu *tmppos;
int tmpcurpos;

tmpcurpos = curpos;
tmppos = scrpos;
if ( flag[0] == 'D') {
while ( tmpcurpos % m_conf.m_col != m_conf.m_col-1) {
tmppos = tmppos->next;
tmpcurpos++;
}
tmppos = tmppos->next;
}

for (tmpcurpos = 0; tmpcurpos < m_conf.m_col; tmpcurpos++) {
wmove(curw, m_conf.m_lengh-1, (tmpcurpos%m_conf.m_col)*m_conf.m_wight/m_conf.m_col+m_conf.m_col);
wprintw(curw, "%s", tmppos->item);
last=tmppos;/* last 为本页最后一个结点指针 */
begin=tmppos;
tmppos = tmppos->next;
if (tmppos == NULL)
break;
}
}
/* 取指定菜单参数函数 */
void getmenuconf(menu_code)
short menu_code;
{
FILE *fp;
char menu_buff[0x100];

if ((fp = fopen("menu.conf", "r"))==NULL) {
printw( "can not open menu config file");
refresh();
endwin();
exit(-1);
}
while( fgets(menu_buff, 0x100, fp)!=NULL ) {
get_m_conf(menu_buff);
if (m_conf.menu_code == menu_code)
break;
}
return ;
}
/* 取指定菜单参数处理函数 */
void get_m_conf(menu_conf)
char *menu_conf;
{
register i, j, k;
char buff[20];

j = k = 0;
for (i = 0; i < strlen(menu_conf); i++) {
if ( menu_conf[i] == '!' ) {
j++;
if ( j == 1) {
k = i+1;
continue;
}
switch(j) {
case 2:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.menu_code = atoi(buff);
k=i+1;
break;
case 3:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.last_code = atoi(buff);
k=i+1;
break;
case 4:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.bord_flag = atoi(buff);
k=i+1;
break;
case 5:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.m_wight = atoi(buff);
k=i+1;
break;
case 6:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.m_lengh = atoi(buff);
k=i+1;
break;
case 7:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.m_col = atoi(buff);
k=i+1;
break;
case 8:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.m_bx = atoi(buff);
k=i+1;
break;
case 9:
memcpy(buff, &menu_conf[k], i-k);
buff[i-k]=0;
m_conf.m_by = atoi(buff);
k=i+1;
break;
default:
break;
}
}
}
}
/* 取指定项参数处理函数 */
void get_m_item(menu_item)
char *menu_item;
{
register i, j, k;
char buff[80];

j = k = 0;
for (i = 0; i < strlen(menu_item); i++) {
if ( menu_item[i] == '!' ) {
j++;
if ( j == 1) {
k = i+1;
continue;
}
switch(j) {
case 2:
memcpy(buff, &menu_item[k], i-k);
buff[i-k] = 0;
m_item.menu_code = atoi(buff);
k=i+1;
break;
case 3:
memcpy(buff, &menu_item[k], i-k);
buff[i-k] = 0;
m_item.item_order = atoi(buff);
k=i+1;
break;
case 4:
memcpy(buff, &menu_item[k], i-k);
buff[i-k] = 0;
strcpy(m_item.item,buff);
k=i+1;
break;
case 5:
memcpy(buff, &menu_item[k], i-k);
buff[i-k] = 0;
strcpy(m_item.prog,buff);
k=i+1;
break;
case 6:
memcpy(buff, &menu_item[k], i-k);
buff[i-k] = 0;
m_item.submenu_code = atoi(buff);
k=i+1;
break;
default:
break;
}
}
}
}
/* 初始化资源*/
void initial() /* 自定开启 curses 函式 */  
{
initscr();
cbreak();
nonl();
noecho();
intrflush(stdscr,FALSE);
keypad(stdscr,TRUE);
refresh();
}
/* 按键等待函数 */
void keycont()
{
fprintf(stderr, "按键继续...");
getchar();
}
/* 运行可执行程序函数 */
void execprog()
{
def_prog_mode();
        //system("clear");
//fprintf(stderr, "%s: \n", scrpos->item);
system(scrpos->prog);
reset_prog_mode();
keycont();
initial();
touchwin(boxwin);
touchwin(curw);
keypad(curw, TRUE);
wrefresh(boxwin);
wrefresh(curw);
}
/* 清除窗口函数 */
void clearwin()
{
wmove(boxwin, 0, 0);
wclrtobot(boxwin);
wrefresh(boxwin);
delwin(curw);
delwin(boxwin);
}[/code:1:d1e7766ace] :D  :D

 horse 回复于:2003-06-24 07:59:23
我的已经修改过了,不过,还是多谢了。

 天祥星辰 回复于:2003-06-24 09:22:12
好! 继续努力!

 无双 回复于:2003-06-24 11:58:03

直接跟到后面就可以了

我修改过了
修改的地方也和你一样

 yingxiongl 回复于:2003-06-25 16:18:26
怎么我在linux7.3下运行出错了?

 kinghood 回复于:2003-06-25 18:35:32
顶一下!

 cxzty 回复于:2003-06-25 19:21:15
辛苦了!谢谢!收下!

 ncwyj 回复于:2003-06-25 21:56:20
谢谢!

 tty1a 回复于:2003-07-12 17:10:21
请问如何在这个程序中动态显示时间?

 蓝色键盘 回复于:2003-07-22 11:06:17
偶置精吧,好不容易发现的,呵呵

 jenson0015 回复于:2003-08-07 22:11:03
对于菜单中汉字而导致的乱屏怎么处理???

 jenson0015 回复于:2003-08-07 22:18:13
程序在退出时怎么都没有free momery???

 yzyt 回复于:2004-02-13 16:34:09
为什么编译后执行会出现Floating exception(coredump)?

 杀无赦 回复于:2004-09-01 08:42:56
可否提供一个menu.conf 和menu.def的文件范本,想使用,可是看程序太累了,研究好久不知如何编辑这两个文件更好,谢谢

 likfan 回复于:2005-08-07 21:02:37
有效果图吗?

 sdccf 回复于:2005-08-08 08:09:35
怎么还是出现编译错误?


"menu1.c", line 409: error: Syntax error before or at: }
"menu1.c", line 417: warning: statement not reached
"menu1.c", line 418: error: undefined symbol: menu_conf
"menu1.c", line 427: error: cannot dereference non-pointer type
"menu1.c", line 433: error: cannot dereference non-pointer type
"menu1.c", line 439: error: cannot dereference non-pointer type
"menu1.c", line 445: error: cannot dereference non-pointer type
"menu1.c", line 451: error: cannot dereference non-pointer type
"menu1.c", line 457: error: cannot dereference non-pointer type
"menu1.c", line 463: error: cannot dereference non-pointer type
"menu1.c", line 469: error: cannot dereference non-pointer type
"menu1.c", line 481: error: Syntax error before or at: void
"menu1.c", line 488: error: undefined symbol: menu_item
"menu1.c", line 497: error: cannot dereference non-pointer type
"menu1.c", line 503: error: cannot dereference non-pointer type
"menu1.c", line 509: error: cannot dereference non-pointer type
"menu1.c", line 515: error: cannot dereference non-pointer type
"menu1.c", line 521: error: cannot dereference non-pointer type
"menu1.c", line 533: error: Syntax error before or at: void

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有