/*         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; }
|
|