例程说明

在这里插入图片描述

  • 在Dev-C++编译器上实现双向链表多级菜单界面设计框架


一、菜单项结构体


/* 菜单项结构体 */
typedef struct xSuperMenuItem
{
    const u8 * Name;                /* 菜单名称 */
    void (* EventHandler)(void);    /* 菜单执行函数 */
    struct xSuperMenuItem * Parent; /* 父菜单 */
    struct xSuperMenuItem * Childr; /* 子菜单 */
    struct xSuperMenuItem * Next;   /* 同级下一个菜单 */
    struct xSuperMenuItem * Prev;   /* 同级上一个菜单 */
}xSuper_MenuItem_TypeDef, * xSuper_MenuItem_TypeDef_t;


二、添加子菜单项(组)


/* 添加子菜单项 */
void vAdd_ChildrenMenu_Item(xSuper_MenuItem_TypeDef * parent, xSuper_MenuItem_TypeDef * childr) 
{
    /* 设置子父菜单 */
    childr->Parent = parent;

    /* 第一项子菜单 */
    if (parent->Childr == NULL)
    {
        parent->Childr = childr;
    }
    else
    {
        /* 从第一项子菜单查找 */
        xSuper_MenuItem_TypeDef * temp = parent->Childr;
        while (temp->Next)
        {
            /* 查找后一项子菜单 */
            temp = temp->Next;
        }

        /* 同级下一项菜单 */
        temp->Next = childr;

        /* 同级上一项菜单 */
        childr->Prev = temp;
    }
}


/* 添加子菜单组 */
void vAdd_ChildrenMenu_Group(xSuper_MenuItem_TypeDef ** group, u8 num) 
{
    u8 i = 0;

    for (i = 1; i < num; ++i)
    {
        vAdd_ChildrenMenu_Item(group[0], group[i]);
    }
}


三、显示子菜单项


/* 显示子菜单项 */
void vDisplay_ChildrenMenu_Item(xSuper_MenuItem_TypeDef * menuItem) 
{
    u8 i = 1;
    xSuper_MenuItem_TypeDef * temp = NULL;

    system("cls");
    HANDLE handler = GetStdHandle(STD_OUTPUT_HANDLE);
    printf("******************** ");
    SetConsoleTextAttribute(handler, BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | FOREGROUND_RED);
    printf("%s %08X ", menuItem->Name, menuItem);
    SetConsoleTextAttribute(handler, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
    printf("********************\r\n");


    temp = menuItem->Childr;
    while (temp) 
    {
        printf("[%03u] %s %08X\r\n", i++, temp->Name, temp);
        temp = temp->Next;
    }
    printf("*****************************************************************\r\n\r\n\r\n");

        
    if (AppCurMenu->Parent)
    {
        printf("0. Return to previous menu\r\n");
    } 
    else
    {
        printf("0. Log out\n");
    }
    printf("Please select operation: ");
    // printf("Compiler Date123 : %d \r\n", GetTickCount64()); //GetTickCount();
}



四、用户输入处理


/* 用户输入处理 */
void vUserInput_Handler(int index) 
{
    struct xSuperMenuItem * item = AppCurMenu->Childr;
    u8 num = 0;


    while (item && (++num < index))
    {
        item = item->Next;
    }

    if (index == 0)
    {
        if (AppCurMenu->Parent)
        {
            AppCurMenu = AppCurMenu->Parent;
        }
        else 
        {
            exit(0);
        }
    }
    else if (item)
    {
       if (item->EventHandler)
       {
           item->EventHandler();
       }
       if (item->Childr)
       {
           AppCurMenu = item;
       }
    }
}


五、初始化菜单项


xSuper_MenuItem_TypeDef * AppCurMenu = NULL;


static void vDisplayVer(void) 
{
    system("cls");
    printf("Software Version  :V2.3.8\r\n");
    printf("Hardware Version  :V1.6.0\r\n");
    printf("Date : %s  %s\r\n", __DATE__, __TIME__); 
    printf("Press Any Key To Return......");
    getch();
}

static void vSystemReset(void) 
{
    system("cls");
    printf("System Is Restarting......\r\n");
    printf("Press Any Key To Return......");
    getch();
}

static void vFactoryReset(void)
{
    system("cls");
    printf("System Factory Reset......\r\n");
    printf("Press Any Key To Return......");
    getch();
}


static void vSet_Sys_Unit(void)
{
    system("cls");
    printf("System Unit M......\r\n");
    printf("Press Any Key To Return......");
    getch();
}

static void vSet_Off_Time(void)
{
    system("cls");
    printf("System Off Time 120S......\r\n");
    printf("Press Any Key To Return......");
    getch();
}

static void vSet_Backlight(void)
{
    system("cls");
    printf("System Backlight 80%%......\r\n");
    printf("Press Any Key To Return......");
    getch();
}

static void vSys_State_Info(void)
{
    system("cls");

    const char * info1 =\
    "\r\n\
    Read Demar Param OK...0\r\n\
    --------------------- Demar Param Info ----------------------\r\n\
                00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  \r\n\
    -------------------------------------------------------------\r\n\
    0x0801F800  5A 6C 00 00 7C FC 00 00 00 00 00 00 00 00 3E FE  \r\n\
    0x0801F810  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  \r\n\
    0x0801F820  00 00 C2 01 00 00 00 00 00 00 00 00 84 03 00 00  \r\n\
    0x0801F830  00 00 00 00 00 00 00 00 00 00 00 00 00 96 00 00  \r\n\
    0x0801F840  00 00 00 00 B7 FF FF FF 72 FE FF FF B9 FF FF FF  \r\n\
    0x0801F850  A5 AE 8C 01 00 00 00 00 00 00 00 00 00 00 00 00  \r\n\
    0x0801F860  00 00 00 00 00 00 4E 0A 00 00 00 00 00 00 00 00  \r\n\
    0x0801F870  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6A  \r\n\
    -------------------------------------------------------------\r\n\
    ";

    const char * info2 = \
    "\r\n\
    Read Operat Param OK...2\r\n\
    --------------------- Operat Param Info ---------------------\r\n\
                00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  \r\n\
    -------------------------------------------------------------\r\n\
    0x0801F040  3D 2A 02 00 04 00 00 03 01 02 00 00 00 00 00 00  \r\n\
    0x0801F050  00 00 AA 00 08 52 00 00 00 00 00 00 00 00 00 77  \r\n\
    -------------------------------------------------------------\r\n\
    ";

    printf("%s\r\n\r\n", info1);
    printf("%s\r\n",     info2);
    printf("Press Any Key To Return......");
    getch();
}


static xSuper_MenuItem_TypeDef Main_Menu     = { "Main Menu",         NULL, NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Sys_Set_Menu  = { "System Settings",   NULL, NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Sys_Mag_Menu  = { "System Management", NULL, NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Info_Que_Menu = { "Information Query", NULL, NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef * Main_Menu_Page[] = 
{
    &Main_Menu,
    &Sys_Set_Menu,
    &Sys_Mag_Menu,
    &Info_Que_Menu,
};

static xSuper_MenuItem_TypeDef Set_Sys_Unit  = { "Set System Unit",          &vSet_Sys_Unit,  NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Set_Off_Time  = { "Set Off Time ",            &vSet_Off_Time,  NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Set_Backlight = { "Set Backlight Brightness", &vSet_Backlight, NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef * Sys_Set_Page[] = 
{
    &Sys_Set_Menu,
    &Set_Sys_Unit,
    &Set_Off_Time,
    &Set_Backlight,
};


static xSuper_MenuItem_TypeDef Sys_State_Info = { "Sys State Info", &vSys_State_Info,   NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef * Sys_Mag_Page[] = 
{
    &Sys_Mag_Menu,
    &Sys_State_Info,
};

static xSuper_MenuItem_TypeDef Dis_Ver_Menu    = { "Display Version", &vDisplayVer,   NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Sys_Reset_Menu  = { "System Restart",  &vSystemReset,  NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef Fact_Reset_Menu = { "Factory Reset",   &vFactoryReset, NULL, NULL, NULL, NULL };
static xSuper_MenuItem_TypeDef * Sys_Info_Page[] = 
{
    &Info_Que_Menu,
    &Dis_Ver_Menu,
    &Sys_Reset_Menu,
    &Fact_Reset_Menu,
};


void vInit_Menu(void) 
{
    u8 num = sizeof(Main_Menu_Page) / sizeof(Main_Menu_Page[0]);
    vAdd_ChildrenMenu_Group(Main_Menu_Page, num);

    num = sizeof(Sys_Set_Page) / sizeof(Sys_Set_Page[0]);
    vAdd_ChildrenMenu_Group(Sys_Set_Page, num);

    num = sizeof(Sys_Mag_Page) / sizeof(Sys_Mag_Page[0]);
    vAdd_ChildrenMenu_Group(Sys_Mag_Page, num);

    num = sizeof(Sys_Info_Page) / sizeof(Sys_Info_Page[0]);
    vAdd_ChildrenMenu_Group(Sys_Info_Page, num);

    AppCurMenu = &Main_Menu;
}



六、主函数


int main(int argc, char *argv[]) 
{
    int index = 0;

    
    vInit_Menu();
    while (1) 
    {
        vDisplay_ChildrenMenu_Item(AppCurMenu);
        scanf("%d", &index);
        vUserInput_Handler(index);
    }

    printf("Compiler Date : %s  %s\r\n", __DATE__, __TIME__);
	while(1);
	return 0;
}


七、测试结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐