2013-07-10 47 views
1

當試圖動態實現菜單在C沒有資源文件++礦的應用與類似下面的界面,我遇到了一個問題:C++ - WINAPI - 遞歸創建菜單?

Menu menu_main__ = { 
    Menu("File", { 
     Menu("Save Configuration", {}), 
     Menu("Save Configuration As...", {}), 
     Menu(nullptr, {}), 
     Menu("Something", { 
      Menu("Yay!", {}) 
     }) 
    }), 
    Keybutter::Menu("Help", { 
     Menu("Contents", {}), 
     Menu(nullptr, {}), 
     Menu("About", {}), 
    }) 
}; 

下面的是菜單類的構造函數:

Menu(Menu const& menu_) = default; 
Menu(Menu&& menu_) = default; 
Menu(std::initializer_list<Menu>&& menus_sub__); 
Menu(std::nullptr_t const&, std::initializer_list<Menu>&& menus_sub_); 
Menu(std::string&& name_, std::initializer_list<Menu>&& menus_sub_); 

現在,我想通過遞歸實現菜單創建的唯一可行方法就是使用遞歸。我結束了我的窗口類內使用lambda遞歸,如下所示:

std::vector<Menu> menus; 

static unsigned int id_menu_sub = 0; 

std::function<void (HMENU const&, std::string const&, std::vector<Menu> const&)> create_menus_sub__; 
create_menus_sub__ = [&](HMENU const& menu_, std::string const& name_menu_, std::vector<Menu> const& menu_sub_) -> void{ 
    if(menu_sub_.empty()){ 
     return; 
    } 
    else{ 
     HMENU&& menu_sub__ = CreatePopupMenu(); 
     for(unsigned int i__ = 0; i__ < menu_sub_.size(); ++i__){ 
      if(menu_sub_[i__].menus_sub().empty()){ 
       if(menu_sub_[i__].name.empty()){ 
        AppendMenu(menu_sub__, MF_SEPARATOR, ++id_menu_sub, NULL); 
       } 
       else{ 
        AppendMenu(menu_sub__, (menu_sub_[i__].menus_sub().empty()) ? MF_STRING : MF_POPUP | MF_STRING, ++id_menu_sub, menu_sub_[i__].name.c_str()); 
       } 
      } 
      else{ 
       create_menus_sub__(menu_, menu_sub_[i__].name, menu_sub_[i__].menus_sub()); 
      } 
     } 
     AppendMenu(menu_, MF_POPUP | MF_STRING, reinterpret_cast<UINT>(menu_sub__), name_menu_.c_str()); 
    } 
}; 
for(unsigned int i__ = 0; i__ < menus.size(); ++i__){ 
    HMENU&& menu__ = CreateMenu(); 
    create_menus_sub__(menu__, menus[i__].name, menus[i__].menus_sub()); 
    SetMenu(handle_window, menu__); 
} 

原來,它沒有按預期工作。下面是結果:而不是被在「文件」菜單項

enter image description here

「東西」,現在是在錯誤的位置。這是我嘗試用一​​個好的,但有些可疑的C++接口動態地創建菜單。我如何使用遞歸來遞歸地製作菜單?我的代碼如何修復?我希望我提供了足夠的信息。

回答

2

當您遞歸調用lambda時,您將指針傳遞給menu_而不是menu_sub_,這意味着子菜單將被添加到頂層而不是當前子菜單。

不錯的使用C++ 11功能btw! :)

+0

謝謝你,這個伎倆。我可能會用一個改進的代碼片段上傳答案。我可以很好地理解C++(11)中的新特性並使用它們,但是更重要的數學概念,如遞歸,我很難理解,更不用說在代碼中實現了。事實上,這可能是我第一次利用遞歸的優勢。不是開玩笑!我更喜歡迭代,但它並不總是一個理想的解決方案,就像在這種情況下一樣。 – Helixirr