C控制台菜单
前几天看某个作业贴,有个要求是菜单必须能用光标选择,一时无事,就把这个功能给做了,算是给各位写作业的同学锦上添花吧a.h
#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);
}
}
#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);
}
}
下面的a.cpp是演示如何使用
#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;
}
#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;
}
以上程序WinXP(SP2)+VC6测试通过
顺便为了照顾不得不使用TC的同学,特别修改了一个TC版,TC2测试通过
附件中包含VC和TC两种版本
C控制台菜单.rar
(9.61 KB)