搜索产品 minitos开源嵌入式操作系统 minitos Windows minitos Menu
首 页 产品展厅 精品文章 嵌入式资讯 下载中心 论坛 嵌入式城市 技术应用
 收藏社区
 免费注册
 用户登陆
 帮助中心
社区首页 业界新闻 精品文章 下载中心 minitos2站 在线学习 论坛 嵌入式提问交流学习 供求信息 留言 minitos操作系统 测试
今天是:2010年9月10日 星期五   您现在位于: miniTOS生活社区 →  嵌入式菜单核心文件menu.c
谷歌搜本站效率更高
嵌入式菜单核心文件menu.c
2009年3月24日  作者:  发布人:专业嵌入式网站      本文已被浏览 227 次
/*
    
   minitos Menu 采用和Windows一样的菜单设计API,快速设计嵌入式菜单系统。
   可以根据所选择的菜单触发一个子程序运行。(酷吧,像delphi的事件函数一样:) )

 minitos就是 mini Task OS,意思是迷你的rTOS.

http://www.minitos.com  minitos嵌入开发网主站
http://www2.minitos.com minitos嵌入开发网2站
http://net.minitos.com   minitos嵌入开发网网络站
http://www2.minitos.com/bbs 嵌入式论坛
http://ask.embed.cc 嵌入式提问吧

minitos 嵌入操作系统 : http://www.minitos.com/index.htm
minitos Windows C++嵌入图形系统 http://www.minitos.com/index.htm

  
    本文实现minitos Menu 的菜单API实现文件
 created by Linls,2003.8
*/



/*
菜单实现文件
*/

#include <string.h>
#include "Menu.h"


/*内存分配函数*/
void *MO_Malloc(UINT uiSize)
{
/* 需要移植的函数 */
 return  malloc(uiSize);
}
void MO_Free(void *pMem)
{
/* 需要移植的函数 */
 
 pMem = NULL;
}

void MO_Display(char *szName)
{
/* 需要移植的函数 */
 printf("%s\n",szName); 
}

/*
初始化菜单项列表,如上面的ItemExp[2],并建立一个POPUP菜单指向该列表
uiNum --菜单项列表的项数
Input:  pItem --指向菜单项列表的第一项
    uiNum --列表由多少项
return : 返回该POPUP菜单的指针
*/
MENUAPI HMENU InitMenuItemList(MENUITEM pItem[],UINT uiNum)
{
 PMENUPOPUP pMenu;
 UINT i;

 if(uiNum==0)
  return 0;

 pMenu = (PMENUPOPUP) CreatePopupMenu();

  /*pNext指针处理*/
 for(i=0;i<uiNum-1;i++)
 {  
  pItem[i].pNext= &(pItem[i+1]);
 }
 pItem[uiNum-1].pNext = NULL;


  /*pPrev指针处理*/
 for(i=uiNum  i>0  i--)
 {  
  pItem[i].pPrev= &(pItem[i-1]);
 }
 pItem[0].pPrev = NULL;

  /*头指针*/
 pMenu->pHead = &(pItem[0]);

  /*头指针*/
 pMenu->pTail = &(pItem[uiNum-1]);

 return (HMENU)pMenu;
}

/*
建立一个空的POPUP菜单
return : 返回该 POPUP菜单
*/
MENUAPI HMENU CreatePopupMenu (void)
{
    PMENUPOPUP pTmp;

    if ( ( pTmp = (PMENUPOPUP)MO_Malloc(sizeof(MENUPOPUP)) )==NULL )
    {
        return 0;
    }
    pTmp->pHead = NULL;
 pTmp->pTail = NULL;
 pTmp->pFarther = NULL;
 pTmp->pFartherPopup = NULL;
    return (HMENU)pTmp;
}

/*
在一个POPUP菜单上最后的项再追加一个菜单项,同Window类似
Input: hMenu --要追加的POPUP菜单
   flags -- MF_POPUP 表示追加的项为POPUP菜单
      其他  表示追加 的是普通菜单项
  ItemID -- 如果flags为MF_POPUP ,则该项表示为POPUP菜单项指针
      如果flags为其他 ,则该项表示为菜单项的ID
  lpContent--菜单项名
return : TRUE --成功
*/
MENUAPI BOOL AppendMenu(HMENU hMenu,UINT flags,UINT ItemID,char * lpContent)
{
 PMENUITEM pTmp,pNode,pOld;
 
 if( !(hMenu) )
 {
  return FALSE;
 }
    if ( ( pTmp =(PMENUITEM) MO_Malloc(sizeof(MENUITEM)) )==NULL )
    {
        return FALSE;
    } 
 
 memset (pTmp, 0, sizeof(MENUITEM));

    pTmp->uiID=ItemID;
    pTmp->uiType = flags;
 pTmp->uiType |= MF_MALLOC; /*动态创建*/
     /*pTmp->dwItemData*/
 memcpy(pTmp->szName,lpContent,MENU_MAX_LEN); /*bug???使用min*/
   /*MAX(MENU_MAX_LEN,strlen(lpContent))); */
    pTmp->uiKey=0; /*无快捷键*/
 pTmp->bExit=TRUE; 
 pTmp->Func=NULL; 
 pTmp->EnterFunc=NULL; 

    if( (flags & MF_POPUP) ==MF_POPUP)
    {
  pTmp->uiID = 0;
     pTmp->hSubMenu=(PMENUPOPUP)ItemID;

   /*设置上级菜单*/
  pTmp->hSubMenu->pFarther = pTmp;
  pTmp->hSubMenu->pFartherPopup =(PMENUPOPUP) hMenu;
 }else
 {
  pTmp->hSubMenu = 0;
 }
 pTmp->pNext=NULL;
      
 pNode=( (PMENUPOPUP)hMenu )->pHead;
 if( !pNode)
 { 
  /*没有菜单,在第一个*/
  ( (PMENUPOPUP)hMenu )->pHead = pTmp;
  ( (PMENUPOPUP)hMenu )->pTail = pTmp;
  pTmp->pPrev = NULL;

  return TRUE;
 }
 while(pNode)
 {
  pOld=pNode;
  pNode=pNode->pNext;/*下一个菜单项 */
 }
  /* 插在最后面 */
 pOld->pNext=pTmp; 
 pTmp->pPrev = pOld;

  /*重新定向尾指针 */
 ( (PMENUPOPUP)hMenu )->pTail = pTmp;

 return TRUE;
}

/*设置菜单项参数
*/
MENUAPI void SetMenuItemParam(PMENUITEM pItem,UINT key,BOOL bExit,void (*Func)(void),void (*EnterFunc)(void))
{
 pItem->uiKey = key;
 pItem->bExit = bExit;
 pItem->Func = Func;
 pItem->EnterFunc = EnterFunc;
}


/*
把一个hMenu菜单挂到上层的一个菜单项pItem中,使之成为一个完整的菜单
pPopupIn --指向pItem的Popup菜单指针
*/
MENUAPI void SetMenuItem(PMENUPOPUP pPopupIn,PMENUITEM pItem,HMENU hMenu)
{
 PMENUPOPUP pPopup=(PMENUPOPUP)hMenu;

 pItem->uiType |=MF_POPUP 
 pItem->hSubMenu=(PMENUPOPUP)hMenu; 
  
  
 pPopup->pFarther=pItem;
 pPopup->pFartherPopup=pPopupIn;
}

/*
在hMenu的POPUP菜单的菜单项的最后再创建一个POPUP菜单项
Input: Title --要创建的Popup菜单项名
       hMenu --
return : 返回已经创建Popup菜单指针
*/
MENUAPI HMENU AppendPopupMenu(HMENU hMenu,char *Title)
{
 HMENU hPopup;
 hPopup = CreatePopupMenu ();
 AppendMenu(hMenu, MF_POPUP, (UINT)hPopup, Title);
 return hPopup;
}
/*
在菜单中删除一个菜单项pItem
如果该菜单项为POPUP类型的菜单项,则返回该Popup菜单,否则返回0
*/
MENUAPI HMENU DeleteMenuItem(HMENU hMenu,PMENUITEM pItem)
{
 PMENUPOPUP pPopup = (PMENUPOPUP)hMenu;
 PMENUPOPUP pRet;

 if ( pItem->pPrev == NULL )
 {
  if ( pItem->pNext == NULL )
  {
   /*只有一项 */
   pPopup->pHead = NULL;
   pPopup->pTail = NULL;
  }else
  {
   /*删除第一项 */
   pItem->pNext->pPrev = NULL;
   pPopup->pHead = pItem->pNext;
  }      
 }else
 {
  if ( pItem->pNext == NULL )
  {
   /*最后一项 */
   pItem->pPrev->pNext = NULL;
   pPopup->pTail = pItem->pPrev;
  }else
  {
   /* 中间 */
   pItem->pPrev->pNext = pItem->pNext;
   pItem->pNext->pPrev = pItem->pPrev;
  }
 }
 
 if( (pItem->uiType & MF_POPUP) ==MF_POPUP )
 {
   /* 返回子菜单 */
  pRet = pItem->hSubMenu;
  
 }else
 {
  pRet = NULL;
 }

 if(  (pItem->uiType & MF_MALLOC) ==MF_MALLOC )
 {
  MO_Free((void *)pItem);
 }
 return (HMENU) pRet;
}

/*
判断是否一个菜单为空菜单(没有菜单项)
*/
BOOL IsMenuNULL(HMENU hMenu)
{
 PMENUPOPUP pMenu = (PMENUPOPUP)hMenu;
 if(pMenu->pHead==NULL)
  return TRUE;
 return FALSE;
}

/*
删除一个Popup菜单
*/
MENUAPI void DestroyMenu(HMENU hMenu)
{
 PMENUITEM pItem;
 PMENUPOPUP pMenu = (PMENUPOPUP)hMenu;
 HMENU hMenuSub;
 if ( IsMenuNULL(hMenu) )
 {
  /*菜单为空,释放Popup空间
  */
  MO_Free( (void*)pMenu );
  return;
 }
 
 pItem = pMenu->pHead;
 while(pItem)
 {
  
  hMenuSub = DeleteMenuItem(hMenu,pItem);
  if(hMenuSub)
  {
   /*使用递归释放下一层子菜单 */
   DestroyMenu(hMenuSub);
  }
   /*取下一个项 */
  pItem = pMenu->pHead;
 }
 /*全部菜单项释放完毕,释放POPUP指针 */
 MO_Free( (void*)pMenu );  
}

/*

以上为菜单数据结构定义和操作

以下为菜单显示操作
菜单显示操作

*/


/*
建立一个菜单实例
*/
MENUAPI HINST  CreateMenuInst(HINST hInst_View)
{
 MENU_INST * p;
 p= (MENU_INST *)MO_Malloc( sizeof(MENU_INST) );
 p->sg_pCurrMenuItem = NULL;
 p->sg_pCurrMenuPopup = NULL;
 p->sg_hInst_View = hInst_View;
 return (HINST)p;
}


/*运行某一级POPUP菜单 */
MENUAPI void MenuStart(HINST hInst, HMENU hMenu)
{
 MENU_INST * p=(MENU_INST * )hInst;
 p->sg_pCurrMenuPopup = (PMENUPOPUP)hMenu;
 p->sg_pCurrMenuItem = p->sg_pCurrMenuPopup->pHead;
}
/*
显示当前任务菜单实例菜单项
*/
void MenuDisplay(HINST hInst)
{
 MENU_INST * p=(MENU_INST * )hInst;
 MO_Display(p->sg_pCurrMenuItem->szName);
 

  /*执行立即显示的函数*/
 if(p->sg_pCurrMenuItem->Func)
 {
  p->sg_pCurrMenuItem->Func();
 }
}


/*向下移动一个菜单 */
void Menu_OnDown(HINST hInst)
{
 MENU_INST * p=(MENU_INST * )hInst;
   /* Popup菜单没有菜单项,菜单设计错误 */
 if( (p->sg_pCurrMenuItem==NULL)||
     (p->sg_pCurrMenuPopup==NULL) )
 {
   /* 菜单容错 */
   return 
 }


  /*最后一个菜单项吗 */
 if(p->sg_pCurrMenuItem->pNext==NULL)
 {
  /*是
  移动到开头第一项 */
  p->sg_pCurrMenuItem = p->sg_pCurrMenuPopup->pHead;
 }else
 {
  /*移到下一项 */
  p->sg_pCurrMenuItem = p->sg_pCurrMenuItem->pNext;
 }
  /* 显示 */
 MenuDisplay(hInst);
}

/*
向上移动一个菜单
*/
void Menu_OnUp(HINST hInst)
{
 MENU_INST * p=(MENU_INST * )hInst;
   /*Popup菜单没有菜单项,菜单设计错误 */
 if( (p->sg_pCurrMenuItem==NULL)||
     (p->sg_pCurrMenuPopup==NULL) )
 {
   /*菜单容错 */
   return 
 }

  /* 第一个菜单项吗 */
 if(p->sg_pCurrMenuItem->pPrev==NULL)
 {
  /*是
  移动到lastest
  */
  p->sg_pCurrMenuItem = p->sg_pCurrMenuPopup->pTail;
 }else
 {
  /* 移到下一项 */
  p->sg_pCurrMenuItem = p->sg_pCurrMenuItem->pPrev;
 }
  /*显示 */
 MenuDisplay(hInst);
}

/*
确认后返回菜单的ID
return : 0--进入下一级子菜单
     其他 --所选菜单的ID
*/
UINT Menu_OnOK(HINST hInst)
{
 MENU_INST * p=(MENU_INST * )hInst;
  
 /*子菜单 */
 if( ( p->sg_pCurrMenuItem->uiType & MF_POPUP )==MF_POPUP )
 {
   /* Popup类型没有子菜单,菜单设计错误 */
  if (p->sg_pCurrMenuItem->hSubMenu==NULL)
  {
   /* popup菜单容错 */
   return 0;
  }
   /* Popup菜单没有菜单项,菜单设计错误 */
  if( (p->sg_pCurrMenuItem->hSubMenu->pHead==NULL)||
      (p->sg_pCurrMenuItem->hSubMenu->pTail==NULL) )
  {
   /* popup菜单容错 */
   return 0;
  }

  p->sg_pCurrMenuPopup = p->sg_pCurrMenuItem->hSubMenu;
  
  p->sg_pCurrMenuItem = p->sg_pCurrMenuPopup->pHead;

   /* 显示 */
  MenuDisplay(hInst);
  return 0;

 }else
 {
  UINT ID;

  if( p->sg_pCurrMenuItem->EnterFunc )
  {
   /* 执行回调函数 */
   p->sg_pCurrMenuItem->EnterFunc();
   ID = 0  
  }else
  {
   /* 返回ID,由用户程序自己运行 */
   ID = p->sg_pCurrMenuItem->uiID;
  }
  if( p->sg_pCurrMenuItem->bExit )
  {
    /*执行后退出 */
   p->sg_pCurrMenuPopup = NULL;
   p->sg_pCurrMenuItem = NULL;
  }

    
  return ID;
  
 }
}

/*
返回上一级
*/
void Menu_OnReturn(HINST hInst)
{
 MENU_INST * p=(MENU_INST * )hInst;

   /*Popup菜单没有菜单项,菜单设计错误*/
 if( (p->sg_pCurrMenuItem==NULL)||
     (p->sg_pCurrMenuPopup==NULL) )
 {
   /*菜单容错*/
   return 
 }
 if( p->sg_pCurrMenuPopup->pFarther == NULL)
 {
  /*最上层菜单*/
  return 
 }
 p->sg_pCurrMenuItem = p->sg_pCurrMenuPopup->pFarther;
 p->sg_pCurrMenuPopup = p->sg_pCurrMenuPopup->pFartherPopup;
   
 MenuDisplay(hInst);
}

/*结束菜单
*/
void Menu_onExit(HINST hInst)
{
 MENU_INST * p=(MENU_INST * )hInst;
 p->sg_pCurrMenuPopup = NULL;
 p->sg_pCurrMenuItem = NULL;
}


/*选择菜单
*/
MENUAPI  UINT MenuSelect(HINST hInst,char c)
{
   
 MENU_INST * p=(MENU_INST * )hInst;
 if( (p->sg_pCurrMenuItem==NULL)||
     (p->sg_pCurrMenuPopup==NULL) )
 {
   /*没有处于菜单选择状态,退出   */
  return 0;
 } 

 switch(c)
 {
 case KEY_UP:
  Menu_OnUp(hInst);
  break;

 case KEY_DOWN:
  Menu_OnDown(hInst);
  break;

 case KEY_OK:
  return Menu_OnOK(hInst);
  break;

 case KEY_RETURN:
  Menu_OnReturn(hInst);
  break;

 case KEY_EXIT:
  Menu_onExit(hInst);

  break;
 }
 return 0;
}


 发布人:minitos
 [ → 我要发表文章 ]
上篇文章:嵌入式菜单系统资源文件abc.rc
下篇文章:嵌入式菜单系统核心头文件menu.h
→ 主题所属分类:  minitos → 嵌入式菜单minitosMenu → 『关闭窗口』
 热门文章
 
 skyeye安装运行的详细方法--step by step (20796)
 cygwin下安装arm-elf-gcc一种简便方法 (5939)
 充电器设计及镍氢电池充电方法2 (3394)
 镍氢电池充电方法及充电器(二) (2546)
 Instruction Set: Analysis of SH66x... (2309)
 FAT16文件系统格式详细说明 (2134)
 充电器设计及镍氢电池充电方法1 (1932)
 使用GDB-gnu debug (1690)
 单片机数码管显示驱动设计 (1681)
 一步一步的制作 arm-linux 交叉编译环境 (1577)
 最近更新
 
 QTE 4安装方法 (6月3日)
 真是好文,fc6安装qte,共享 (6月3日)
 超低价部分原装IGBT销售 (6月2日)
 Protel99SE快捷键大全 (6月2日)
 Protel 99 SE的功能特性 (6月2日)
 Protel 99 SE的系统组成 (6月2日)
 设计PCB时抗静电放电(ESD)的方法 (6月2日)
 模拟集成电路 (6月2日)
 数字集成电路 (6月2日)
 语音集成电路 (6月2日)
 文章搜索
 
搜索选项:            
  → 评论内容 (点击查看)
(没有相关评论)
  → 发表我的评论
您的姓名:  您的E-mail:

评论内容:
发表评论:  
娱乐中心 ┋ 关于本站 ┋ 站内短信 ┋ 广告服务 ┋ 友情链接 ┋ 与我在线 ┋ 版权声明  TOP
本站总访问量: 197296 人次 ┋ 最高峰 589 人在线 ┋ 当前有 9 人在线
专业嵌入式网站 [完整型] ┋页面执行时间:171.875 毫秒
Copyright © 2002-2005 minitos.com All Rights Reserved
友情链接: embed嵌入开发网 ┋ 嵌入式提问网 ┋ 嵌入式资料网 ┋ 网络站 ┋ 论坛 ┋