2015-09-23 103 views
0

有一個問題困擾了我很多。
我使用C語言在嵌入式設備中顯示GUI。就像下面的例子。如何降低GUI程序的複雜度

 
  title 
1.xxxx 2.xxxx 
3.xxxx 4.xxxx 
5.xxxx 6.xxxx  

我使用鍵盤選擇我need.but該項目的項目往往有是的子項,我要畫菜單,設定功能again.Just像follwing節目。

 
  title             title             title 
1.xxxx 2.xxxx  press 1  1.xxxx 2.xxxx press 2   1.xxxx 2.xxxx 
3.xxxx 4.xxxx --------------> 3.xxxx 4.xxxx --------------> 3.xxxx 4.xxxx 
5.xxxx 6.xxxx       5.xxxx 6.xxxx       5.xxxx 6.xxxx  

現在我使用下面的代碼寺設置我需要的功能。

GrawAndGetKeyCode("0.xxxx||1.xxxx||2.xxxx||3.xxxx||4.xxxx", "title", &nSelect); 
switch(nSelect) 
{ 
    case 0: 
     fuction(); 
     break; 
    case 1: 
     fuction(); 
     break; 
    case 2: 
     fuction(); 
     break; 
    case 3: 
     fuction(); 
     break; 
    case 4: 
     fuction(); 
     break; 
    default: 
     break; 
} 

我不知道是否有什麼辦法可以使用menu1.item1.subitem2()找出我需要的功能?

非常感謝!

+0

switch語句的要點是什麼? –

+4

您可能想了解[指向函數的指針](http://en.cppreference.com/w/c/language/pointer#Pointers_to_functions),它可以放在數組中,並且可以通過例如'nSelect '。 –

+1

什麼是'menu1.item1.subitem2()'?你的問題不清楚。 –

回答

1

這樣一個簡單的菜單系統可以使用簡單的狀態機來實現。

也許這樣的事情(警告:僞上下的代碼):

typedef void (*handler_t)(void); // Menu handler function type 

handler_t * current_handlers; 
char *current_menu; 

// The top-level menu 
handler_t top_menu_handlers[] = { 
    top_menu_1, 
    top_menu_2, 
    top_menu_3 
}; 

char *top_menu = "..."; // Menu text for the top menu 

// One sub-menu 
handler_t sub_menu_1_handlers[] = { 
    sub_menu_1_1, 
    sub_menu_1_2, 
    sub_menu_1_3 
}; 

char *sub_menu_1 = "..."; 

// Another sub-menu 
handler_t sub_menu_2_handlers[] = { 
    sub_menu_2_1, 
    sub_menu_2_2, 
    sub_menu_2_3 
}; 

char *sub_menu_2 = "..."; 

// ... 

// Initialization 
current_handlers = top_menu_handlers; 
current_menu = top_menu; 

// The state machine 
for (;;) // Infinite loop 
{ 
    clear_screen(); 
    print_menu(current_menu); 

    int selection = get_input(); 

    current_handlers[selection](); // Call menu function 
} 

// ... 

void top_menu_1(void) 
{ 
    // When user selects `1` in the top menu, go to first sub-menu 
    current_handlers = sub_menu_1_handlers; 
    current_menu = sub_menu_1; 
} 

// ... 
void sub_menu_1_3(void) 
{ 
    // When the user select `3` in the first sub-menu, go back to top menu 
    current_handlers = top_menu_handlers; 
    current_menu = top_menu; 
} 

這是一個很大的工作,以初步建立了,但後來它使代碼更普遍,而且它更容易添加新的替代品或菜單。最重要的是,它可以更加自動化(例如,通過將菜單樹變成實際的樹結構,並使狀態機代碼處理菜單變化而不是使處理函數改變它)。

0

您可能有一個菜單項的結構,每個結構都包含一個要顯示的標籤和一個要調用的函數指針。然後,你的DrawMenuAndExecute函數可能需要一個數組menu_item並繪製它們,接受輸入並執行相應的函數。這是一個工作示例:

#include <stdio.h> 
#include <stdlib.h> 

typedef void (* MENUFUNCPTR)(); 

struct menu_item { 
    const char *menu_item; 
    MENUFUNCPTR func; 
}; 

void DrawMenuAndExecute(struct menu_item *items, size_t n) { 
    size_t i; 
    int opt; 
    int cont = 1; 
    // draw the menu 
    for (i = 0; i < n; ++i) { 
    printf("%3d: %s\n", (int)(i+1), items[i].menu_item); 
    } 
    printf("Your selection: "); 
    while (cont) { 
    scanf("%d", &opt); 
    if (opt > 0 && opt <= n) { 
     cont = 0; 
    } 
    else { 
     printf("Wrong selection, your selection again: "); 
    } 
    } 
    opt--; 
    if (items[opt].func != NULL) { 
    (*(items[opt].func))(); 
    } 
} 

void main_menu(); 
void item1_item1(); 
void item1_item2(); 
void item1(); 
void item2(); 
void item3(); 
void item4(); 

void main_menu() { 
    struct menu_item items [] = { 
    { "Item 1 (has submenu)", &item1 }, 
    { "Item 2 (count to ten)", &item2 }, 
    { "Item 3 (write something)", &item3 }, 
    { "Exit", &item4 } 
    }; 
    DrawMenuAndExecute(items, 4); 
} 

void item1_item1() { 
    printf("Hello, how're you? (since I don't care, I won't let you type.)\n"); 
    item1(); 
} 

void item1_item2() { 
    main_menu(); 
} 

void item1() { 
    // item1 has a sub menu 
    struct menu_item items [] = { 
    { "Write something", &item1_item1 }, 
    { "Previous Menu", &item1_item2 } 
    }; 
    DrawMenuAndExecute(items, 2); 
} 

void item2() { 
    int i = 1; 
    for (; i <= 10; ++i) { 
    printf("%d ", i); 
    } 
    printf("\n"); 
    main_menu(); 
} 

void item3() { 
    printf("Something.\n"); 
    main_menu(); 
} 

void item4() { 
    exit(0); 
} 

int main(int argc, char **argv) { 
    main_menu(); 
}