开启辅助访问 切换到窄版

打印 上一主题 下一主题

menu.c 实现minitos Menu 的菜单API实现文件

[复制链接]
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*
   
   minitos Menu 采用和Windows一样的菜单设计API,快速设计嵌入式菜单系统。
   可以根据所选择的菜单触发一个子程序运行。(酷吧,像windows的事件函数一样 )

minitos就是 mini Task OS.

http://www.dianzixuexi.com  电子学习网
minitos 嵌入操作系统 : http://www.dianzixuexi.com minitos相关频道
minitos Windows C++嵌入图形系统 http://www.dianzixuexi.com
Copyright (C) 福州福拓电子科技有限公司
  
    本文实现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.pNext= &(pItem[i+1]);
    }
    pItem[uiNum-1].pNext = NULL;


        /*pPrev指针处理*/
    for(i=uiNum ; i>0 ; i--)
    {        
        pItem.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;
}




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表