4、选择F:H列,在“公式”选项下的“根据所选内容创建”,在“选定区域创建名称”对话框中,勾选“首行”,按“确定”,完成创建名称;
5、选择二级菜单设置区域,在“数据”选项下的“ 数据有效性 ”中,“设置”选项选择“序列”,来源输入=INDIRECT(A2) 确定;
6、在一级菜单设置区域,点击下拉选项按钮,选择相应的菜单内容;
7、在二级菜单设置区域,点击选项按钮,会d出与一级菜单相对应的二级菜单,供选择。
一个参考程序如下。程序涉及到一些底层库函数的调用和cpu内部寄存器的使用,需要有相当软硬件水准去理解。编译环境:中文win-tc或tc3.0或borland c++
#include <stdio.h>
#include <dos.h>
#include <stdlib.h>
#include <bios.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#define BORDER 1
#define ESC 27
#define REV_VID 0x1e
#define NORM_VID 0x40
char *main_menu[] =
{
"F --- 文件管理",
"D --- 磁盘管理",
"H --- 打印服务",
"X --- 退出菜单",
}
char* sub_menu1[] =
{
"S --- 文件显示",
"P --- 文件打印",
"C --- 文件拷贝",
"D --- 文件删除",
"X --- 返回上级",
}
char* sub_menu2[] =
{
"B --- BOOT区备份",
"R --- BOOT区恢复",
"X --- 返回上级",
}
char* sub_menu3[] =
{
"O --- 打印图形",
"F --- 打印文本",
"X --- 返回上级",
}
void goto_xy(int x, int y) /*将光标移动到指定位置*/
{
union REGS regs
regs.h.ah = 2
regs.h.dl = x
regs.h.dh = y
regs.h.bh = 0
int86( 0x10, ®s, ®s )
}
void save_video( int startx, int endx, int starty, int endy, unsigned int* buf_ptr )
/*将指定区域的视频模式存储到指定的内存中去*/
{
union REGS r
register int i, j
for( i = startyi <endyi++)
for( j = startxj <endxj++ )
{
goto_xy(j, i)
r.h.ah = 8
r.h.bh = 0
*buf_ptr++ = int86( 0x10, &r, &r )
putchar(' ')
}
}
void chineseputs( int x, int y, char *p, int attrib ) /*在指定的位置显示中文字符*/
{
union REGS r
while(*p)
{
r.h.ah = 2
r.h.dl = x++
r.h.dh = y
int86(0x10, &r, &r)
r.h.ah = 9
r.h.bh = 0
r.x.cx = 1
r.h.al = *p++
r.h.bl = attrib
int86( 0x10, &r, &r )
}
}
void disp_box( int x1, int y1, int x2, int y2, int attrib) /*显示边框*/
{
unsigned char* boxchar[6] = {"┏","━","┓","┃","┗","┛"}
register int i
for( i = x1i <= x2i++ )
{
chineseputs( i, y1, boxchar[1], attrib )
chineseputs( i, y2, boxchar[1], attrib )
}
for( i = y1i <= y2i++ )
{
chineseputs( x1, i, boxchar[3], attrib )
chineseputs( x2, i, boxchar[3], attrib )
}
chineseputs( x1, y1, boxchar[0], attrib )
chineseputs( x2, y1, boxchar[2], attrib )
chineseputs( x2, y2, boxchar[5], attrib )
chineseputs( x1, y2, boxchar[4], attrib )
}
void display_menu( char* menu[], int x, int y, int count ) /*显示菜单项*/
{
register int i
for( i = 0i <counti++, x++)
{
goto_xy( x, y )
cprintf( menu[i])
}
}
int is_in( char* s, char c) /*返回字符串中热键的位置*/
{
register int i
for( i = 0*si++ )
if( *s++ == c ) return i + 1
return 0
}
int get_resp( int x, int y, int count, char* menu[], char* keys ) /*获得用户的响应*/
{
union inkey
{
char ch[2]
int i
} c
int arrow_choice = 0, key_choice
y++
goto_xy(x, y)
chineseputs( y, x, menu[0], REV_VID)
for()
{
while(!bioskey(1))
c.i = bioskey(0)
goto_xy( x + arrow_choice, y)
chineseputs( y, x+arrow_choice, menu[arrow_choice], NORM_VID )
if( c.ch[0] )
{
key_choice = is_in( keys, tolower( c.ch[0] ))
if( key_choice ) return key_choice - 1
switch( c.ch[0] )
{
case '\r': return arrow_choice
case ' ': arrow_choice++
break
case ESC : return -1
}
}
else
{
switch( c.ch[1] )
{
case 72: arrow_choice--
break
case 80: arrow_choice++
break
}
}
if( arrow_choice == count ) arrow_choice = 0
if( arrow_choice <0 ) arrow_choice = count - 1
goto_xy( x + arrow_choice, y )
chineseputs( y, x+arrow_choice, menu[ arrow_choice ], REV_VID )
}
}
void restore_video( int startx, int endx, int starty, int endy, unsigned char* buf_ptr )
/*恢复原有的视频方式*/
{
union REGS r
register int i, j
for( j = startxj <endxj++)
for( j = startyj <endyj++ )
{
goto_xy(i, j)
r.h.ah = 9
r.h.bh = 0
r.x.cx = 1
r.h.al = *buf_ptr++
r.h.bl = *buf_ptr++
int86( 0x10, &r, &r )
}
}
int popup( char* menu[], char* keys, int count, int x, int y, int border )
/*d出式菜单的显示*/
{
register int i, len
int endx, endy, choice
unsigned int *p
if((x>24)||(x<0)||(y>79)||(y<0))
{
printf("范围错")
return -2
}
len = 0
for( i = 0i <counti++ )
if( strlen( menu[i]) >len ) len = strlen( menu[i] )
endy = len + 2 + y
endx = count + 1 + x
if((endx+1>24)||(endy+1>79))
{
printf("菜单不匹配")
return -2
}
p = (unsigned int *) malloc((endx-x+1)*(endy-y+1))
if( !p ) exit(1)
save_video( x, endx + 1, y, endy+1, p )
if( border ) disp_box( y, x, endy, endx, YELLOW )
display_menu( menu, x + 1, y + 1, count )
choice = get_resp( x + 1, y, count, menu, keys )
restore_video( x, endx + 1, y, endy + 2, (unsigned char* ) p)
free( p )
return choice
}
int main()
{
int i, j
directvideo = 0
for()
{
clrscr()
goto_xy(0, 0)
textcolor( BLACK )
textbackground( RED )
switch( popup( main_menu, "fdhx", 4,5, 16, BORDER ))
{
case 0:
clrscr()
switch( popup( sub_menu1, "spcdx", 5, 5, 16, BORDER ))
{
case 0:
clrscr()
goto_xy( 24, 20 )
cprintf("你选择了文件显示功能")
getch()
break
case 1:
clrscr()
goto_xy( 24, 20 )
cprintf("你选择了文件打印功能")
getch()
break
case 2:
clrscr()
goto_xy( 24, 20 )
cprintf("你选择了文件拷贝功能")
getch()
break
case 3:
clrscr()
goto_xy(24,20)
cprintf("你选择了文件删除功能")
getch()
break
case 4:
break
default:
break
}
break
case 1:
clrscr()
switch( popup( sub_menu2, "brx", 3, 5, 16, BORDER ))
{
case 0:
clrscr()
goto_xy(24,20)
cprintf("你选择了BOOT区备份功能")
getch()
break
case 1:
clrscr()
goto_xy(24,20)
cprintf("你选择了BOOT区恢复功能")
getch()
break
case 2:
break
default:
break
}
break
case 2:
clrscr()
switch( popup( sub_menu3, "of", 3, 5, 16, BORDER ))
{
case 0:
clrscr()
goto_xy( 24, 20 )
cprintf("你选择了打印图形功能")
getch()
break
case 1:
clrscr()
goto_xy(24,20)
cprintf("你选择了打印文本功能")
getch()
break
case 2:
break
default:
break
}
break
case 3:
case -1:
return 0
default:
break
}
}
return 0
}
那就是你的不是啰。要用vc可以到vc++板块提问,vb/vc调用几个控件就完事了。我原以为你是要用c写出代码。
先看第一层菜单{ 0, 0, 0, 1, 0, MainJob1 }
菜单的索引号为0,这个是可以自己随便定义的,但不要超过255,因为你的索引已经声明uchar了,
第二个0,按下向上键的时候,跳到索引号为0的菜单,也就是,保持现在的界面,第三个0也是一样,第四个1,按下回车的时候,跟到索引号为1的菜单,MainJob1一般是一个当然按键的功能函数,或是界面显示函数
这样说,不知道你能明白不?
{1 ,7 ,2 ,8 ,0 , Dsp Point}
1------是当前的索引号
7------按下向上的时候,跳到7号索引的菜单
2------按下向下的时候,跳到2号索引的菜单
8------按下回车的时候,跳到8号索引的菜单
0------按下回车的时候,跳到0号索引菜单,也就是返回到主界面了
至于说,怎么赋值的,其实就是看你自己想怎么设计你的菜单了,
当前的索引号,你自己定义
按下什么按键时,想跳到哪一个索引的菜单,就是这样了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)