C控制台菜单
前几天看某个作业贴,有个要求是菜单必须能用光标选择,一时无事,就把这个功能给做了,算是给各位写作业的同学锦上添花吧a.h
[quote]
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define DefaultWidth 50
typedef void (*MenuFun)(void);
struct _Menu;
typedef struct _Selection
{
char MenuInfor[100];
MenuFun fun;
_Menu* SubMenu;
}Selection, *PSelection;
typedef struct _Menu
{
PSelection SelectionArray;
int nSelectionCount;
}Menu, *PMenu;
void PrintSame(char c, int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%c", c);
}
}
void ShowMenu(PMenu m,int select, int width)
{
int i, l = m->nSelectionCount;
width = width < DefaultWidth ? DefaultWidth : width;
system("cls");
PrintSame('*', width);
printf("\n");
for (i = 0; i < l; i++)
{
if (i == select)
printf("** ==> ");
else
printf("** ");
printf("%-*s**\n", width - 10, m->SelectionArray[i].MenuInfor);
}
PrintSame('*', width);
printf("\n");
printf("数字键:直接选择 方向键:移动光标 回车:确定 ESC:取消\n");
}
void DynamicMenu(PMenu m, int width)
{
char c = 0;
int select = 0, l = m->nSelectionCount;
while (c != 27)
{
ShowMenu(m, select, width);
c = getch();
if (c == -32)
{
c = getch();
if (c == 72 && select > 0)
select--;
else if (c == 80 && select < l - 1)
select++;
}
else if (c == 13)
if (m->SelectionArray[select].SubMenu == NULL)
m->SelectionArray[select].fun();
else
DynamicMenu(m->SelectionArray[select].SubMenu, width);
else if (c >= 1 + '0' && c <= m->nSelectionCount + '0')
if (m->SelectionArray[c - '1'].SubMenu == NULL)
m->SelectionArray[c - '1'].fun();
else
DynamicMenu(m->SelectionArray[c - '1'].SubMenu, width);
}
}[/quote]
下面的a.cpp是演示如何使用
[quote]
#include "a.h"
#define p(x)\
printf("%s 被调用\n按任意键继续..", x);\
getch()
void f1()
{
p("f1");
}
void f2()
{
p("f2");
}
void f3()
{
p("f3");
}
void f4()
{
p("f4");
}
int main()
{
char c = 0;
Selection s1[4] = {"1.子菜单11", f1, NULL, "2.子菜单12", f2, NULL, "3.子菜单13", f3, NULL, "4.子菜单14", f4, NULL};
Selection s3[2] = {"1.子菜单31", f1, NULL, "2.子菜单32", f2, NULL};
Menu m1 = {s1, 4};
Menu m3 = {s3, 2};
Selection s[3] = {"1.菜单1..", f1, &m1, "2.菜单2", f2, NULL, "3.菜单3..", f3, &m3};
Menu m = {s, 3};
DynamicMenu(&m, 60);
return 0;
}[/quote]
以上程序WinXP(SP2)+VC6测试通过
顺便为了照顾不得不使用TC的同学,特别修改了一个TC版,TC2测试通过
附件中包含VC和TC两种版本
** HighlightCodeV3.1 software by yzfy(雨中飞燕) http://yzfy.org **
*****************************************************************/
[/color][color=#FF0000]#include <stdio.h>
[/color][color=#FF0000]#include <conio.h>
[/color][color=#FF0000]#include <stdlib.h>
[/color][color=#FF0000]#define[/color][color=#FF00FF] DefaultWidth 50
[/color]typedef [color=#0000FF]void [/color](*MenuFun)([color=#0000FF]void[/color]);
[color=#0000FF]struct [/color]_Menu;
[color=#0000FF]typedef struct [/color]_Selection
[color=#800000]{
[/color][color=#0000FF]char [/color]MenuInfor[color=#800000][[/color][color=#8000C0]100[/color][color=#800000]][/color];
MenuFun fun;
_Menu* SubMenu;
[color=#800000]}[/color]Selection, *PSelection;
[color=#0000FF]typedef struct [/color]_Menu
[color=#800000]{
[/color]PSelection SelectionArray;
[color=#0000FF]int [/color]nSelectionCount;
[color=#800000]}[/color]Menu, *PMenu;
[color=#0000FF]void [/color][color=#008080]PrintSame[/color]([color=#0000FF]char [/color]c, [color=#0000FF]int [/color]n)
[color=#800000]{
[/color][color=#0000FF]int [/color]i;
[color=#0000FF]for [/color](i = [color=#8000C0]0[/color]; i < n; i++)
[color=#800000]{
[/color][color=#FF0000]printf[/color]([color=#FF00FF]"%c"[/color], c);
[color=#800000]}
}
[/color][color=#0000FF]void [/color][color=#008080]ShowMenu[/color](PMenu m,[color=#0000FF]int [/color]select, [color=#0000FF]int [/color]width)
[color=#800000]{
[/color][color=#0000FF]int [/color]i, l = m->nSelectionCount;
width = width < DefaultWidth ? DefaultWidth : width;
[color=#008080]system[/color]([color=#FF00FF]"cls"[/color]);
[color=#008080]PrintSame[/color]([color=#FF8000]'*'[/color], width);
[color=#FF0000]printf[/color]([color=#FF00FF]"\n"[/color]);
[color=#0000FF]for [/color](i = [color=#8000C0]0[/color]; i < l; i++)
[color=#800000]{
[/color][color=#0000FF]if [/color](i == select)
[color=#FF0000]printf[/color]([color=#FF00FF]"** ==> "[/color]);
[color=#0000FF]else
[/color][color=#FF0000]printf[/color]([color=#FF00FF]"** "[/color]);
[color=#FF0000]printf[/color]([color=#FF00FF]"%-*s**\n"[/color], width - [color=#8000C0]10[/color], m->SelectionArray[color=#800000][[/color]i[color=#800000]][/color].MenuInfor);
[color=#800000]}
[/color][color=#008080]PrintSame[/color]([color=#FF8000]'*'[/color], width);
[color=#FF0000]printf[/color]([color=#FF00FF]"\n"[/color]);
[color=#FF0000]printf[/color]([color=#FF00FF]"数字键:直接选择 方向键:移动光标 回车:确定 ESC:取消\n"[/color]);
[color=#800000]}
[/color][color=#0000FF]void [/color][color=#008080]DynamicMenu[/color](PMenu m, [color=#0000FF]int [/color]width)
[color=#800000]{
[/color][color=#0000FF]char [/color]c = [color=#8000C0]0[/color];
[color=#0000FF]int [/color]select = [color=#8000C0]0[/color], l = m->nSelectionCount;
[color=#0000FF]while [/color](c != [color=#8000C0]27[/color])
[color=#800000]{
[/color][color=#008080]ShowMenu[/color](m, select, width);
c = [color=#008080]getch[/color]();
[color=#0000FF]if [/color](c == -[color=#8000C0]32[/color])
[color=#800000]{
[/color]c = [color=#008080]getch[/color]();
[color=#0000FF]if [/color](c == [color=#8000C0]72 [/color]&& select > [color=#8000C0]0[/color])
select--;
[color=#0000FF]else if [/color](c == [color=#8000C0]80 [/color]&& select < l - [color=#8000C0]1[/color])
select++;
[color=#800000]}
[/color][color=#0000FF]else if [/color](c == [color=#8000C0]13[/color])
[color=#0000FF]if [/color](m->SelectionArray[color=#800000][[/color]select[color=#800000]][/color].SubMenu == [color=#800080]NULL[/color])
m->SelectionArray[color=#800000][[/color]select[color=#800000]][/color].[color=#008080]fun[/color]();
[color=#0000FF]else
[/color][color=#008080]DynamicMenu[/color](m->SelectionArray[color=#800000][[/color]select[color=#800000]][/color].SubMenu, width);
[color=#0000FF]else if [/color](c >= [color=#8000C0]1 [/color]+ [color=#FF8000]'0' [/color]&& c <= m->nSelectionCount + [color=#FF8000]'0'[/color])
[color=#0000FF]if [/color](m->SelectionArray[color=#800000][[/color]c - [color=#FF8000]'1'[/color][color=#800000]][/color].SubMenu == [color=#800080]NULL[/color])
m->SelectionArray[color=#800000][[/color]c - [color=#FF8000]'1'[/color][color=#800000]][/color].[color=#008080]fun[/color]();
[color=#0000FF]else
[/color][color=#008080]DynamicMenu[/color](m->SelectionArray[color=#800000][[/color]c - [color=#FF8000]'1'[/color][color=#800000]][/color].SubMenu, width);
[color=#800000]}
}
[/color][/size][/font][/quote]
我试试看,不过好像有不少可以省略的标签哦,难道我下的这个不是最新版的? 楼主
下了
学习~~
大概的看了一下
果然我是菜鸟
水平就是不够
要写出这个水平还得有一定时间 ddddd
页:
[1]
