树状菜单实现

多级菜单编程实现

1)菜单结构

​ 菜单结构采用树状结构,由若干个节点组成多级菜单。每个节点由当前层级节点数、标题,操作函数、父节点和子节点构成,如下代码所示。

typedef struct Menu{uint8_t MenuNodes;		//当前层节点数目 char *MenuName;		//菜单标题void (*func)(uint16_t key);			//节点函数const struct Menu *Parent;	//父节点const struct Menu *Child;	//子节点	
}Menu_typedef;

2)菜单定义

​ 这里我们实现一个多媒体管理菜单

​ 【我的音乐】
​ ----【经典音乐】
​ --------【曲目1】
​ --------【曲目2】
​ ----【流行音乐】
​ 【我的文档】
----【电子书】
​ ----【说明书】

代码实现如下:

const Menu_typedef MainMenu[2] = {				//一级菜单{2, "我的音乐", NullSubs, NULL, MusicMenu},{2, "我的文档", NullSubs, NULL, DocMenu}	
};const Menu_typedef MusicMenu[2] = {				//二级菜单{2, "经典音乐", NullSubs, MainMenu, Music_1_Menu},{2, "流行音乐", NullSubs, MainMenu, NULL}
};const Menu_typedef DocMenu[2] = {					//二级菜单{2, "电子书", NullSubs, MainMenu, Doc_1_Menu},{2, "说明书", NullSubs, MainMenu, NULL}
};const Menu_typedef Music_1_Menu[2] = {				//三级菜单{2, "曲目1", MusicPlayer, MusicMenu, NULL},{2, "曲目2", MusicPlayer, MusicMenu, NULL},	
};const Menu_typedef Doc_1_Menu[1] = {				//三级菜单{2, "语文", Reader, DocMenu, NULL}
};

定义一个节点,用来保存当前节点信息,初始化指向主菜单

Menu_typedef *MenuPoint = (Menu_typedef*)MainMenu;
char UserChoose = 0; 		//当前层级节点序号

定义一个空函数,补充没有操作的节点。

void NullSubs(uint16_t key) 					
{ }

实现音乐播放函数(省略)

void MusicPlayer(uint16_t key) 					
{ switch(UserChoose){case 0://play music 1break;case 1://play music 2break;	}
}

实现文档阅读器(省略)

void MusicPlayer(uint16_t key) 					
{ if(key ==switch(UserChoose){case 0://语文break;      }
}

3)菜单操作

​ 菜单操作由以下功能组成:上、下、返回、确定。

​ 菜单任务的入口函数为按键操作值,根据用户的输入设备传入

/*** @brief  菜单选择.* @Note	* @param 	keyvalue 输入按键* @retval None*/
void MenuTask(uint16_t Keyvalue)	
{if(OperationFunc == 0){	if(Keyvalue){switch(Keyvalue) {      case UP:  //向上			UserChoose--;if (UserChoose < 0){ UserChoose = MenuPoint->MenuNodes - 1;	//跳转到最后一项} break; case ESC: 	//	返回OperationFunc = 0;if (MenuPoint[UserChoose].Parent != NULL)	//父级是否存??{MenuPoint = (Menu_typedef*)MenuPoint[UserChoose].Parent; UserChoose = 0;} break;case DOWN: 	//向下UserChoose ++; if (UserChoose > MenuPoint->MenuNodes - 1) { UserChoose = 0;					//跳转到子级菜单的第一项} break; 				case ENTER: 	//	ENTER if (MenuPoint[UserChoose].func != NullSubs)	//判断是否有行为函数{ Flag.OperationFunc = 1;					//启动函数操作标志layernumber++;					} else if (MenuPoint[UserChoose].Child != NULL) //判断子级是否为空{ MenuPoint = (Menu_typedef*)MenuPoint[UserChoose].Child; //进入子级UserChoose = 0;    						//跳转到子级菜单的第一}				break;}}	Keyvalue = 0;		//清零,防止直接ENTER		Dipstr = MenuPoint[UserChoose].MenuName;		//保存当前菜单标题,输出到显示设备}if(OperationFunc == 1){(*MenuPoint[UserChoose].func)(Keyvalue);         //执行函数操作		}}

4)结语

​ 这个树状菜单结构具备较好的扩展性和移植性,可以很方便的移植到其他平台,而且结构使用稳定,有问题请留言。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部