GetSubMenu

  name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-5572165936844014&dt=1193665761703&lmt=1193665780&format=336x280_as&output=html&correlator=1193665761687&url=http%3A%2F%2Fwww.codeguru.cn%2Fpublic%2Fiframe%2Fwinapiiframe.htm&color_bg=FFFFFF&color_text=000000&color_link=000000&color_url=FFFFFF&color_border=FFFFFF&ad_type=text&ga_vid=1285758818.1193665762&ga_sid=1193665762&ga_hid=111695597&flash=9&u_h=768&u_w=1024&u_ah=740&u_aw=1024&u_cd=32&u_tz=480&u_his=8&u_java=true" frameborder="0" width="336" scrolling="no" height="280" allowtransparency="allowtransparency">     函数功能:该函数取得被指定菜单激活的下拉式菜单或子菜单的句柄。

    函数原型:HMENU GetSubMenu(HMENU hMenu,int nPos);

    参数:

    hMenu:菜单句柄。

    nPos:激活下拉式菜单或子菜单的菜单项相对于零的位置。

    返回值:如果函数调用成功,返回值是菜单项激活的下拉式菜单或子菜单的句柄。如果菜单项没有激活一个下拉式菜单或子菜单,返回值是NULL。

    速查:Windows NT:3.1及以上版本;Wiodows:95及以上版本;Windows CE:1.0及以上版本;头文件:Winuser.h;输入库:user32.lib。

/** * @file Menu.h * @brief 菜单导航系统头文件 * @author huang huan tao * @date 2025/09/28 */ #ifndef MENU_SYSTEM_H #define MENU_SYSTEM_H #include <vector> #include <string> #include <iostream> #ifdef _WIN32 #include <conio.h> #include <windows.h> #else #include <termios.h> #include <unistd.h> #include <sys/select.h> #endif /** * @class Menu * @brief 表示一个菜单及其子菜单项的类 */ class Menu { private: std::string m_mainName; // 主菜单名称 std::vector<std::string> m_subMenus; // 子菜单项列表 public: /** * @brief 构造函数 * @param mainName 主菜单名称 * @param subs 子菜单项列表 */ Menu(const std::string& mainName, const std::vector<std::string>& subs); /// @brief 获取主菜单名称 const std::string& getMainName() const; /// @brief 获取子菜单项列表 const std::vector<std::string>& getSubMenus() const; /// @brief 获取子菜单项数量 size_t getSubMenuCount() const; /** * @brief 获取指定索引的子菜单项 * @param index 子菜单索引 * @return 子菜单项名称 * @note 索引越界时返回最后一个子菜单 */ const std::string& getSubMenu(size_t index) const; }; /** * @class MenuManager * @brief 管理菜单导航和用户交互的类 */ class MenuManager { private: std::vector<Menu> m_menus; // 菜单列表 size_t m_currentMainIndex = 0; // 当前选择的主菜单索引 size_t m_currentSubIndex = 1; // 当前选择的子菜单索引 size_t m_targetMainIndex; // 目标主菜单索引 size_t m_targetSubIndex; // 目标子菜单索引 /** * @brief 清空控制台屏幕(跨平台) * @note Windows使用cls,Linux/Mac使用clear */ void clearScreen() const; /** * @brief 设置非阻塞输入模式 * @note Linux/Mac平台关闭行缓冲和回显 */ void setupNonBlockingInput(); /** * @brief 根据名称查找主菜单索引 * @param name 主菜单名称 * @return 主菜单索引,未找到时返回0 */ size_t findMainIndex(const std::string& name) const; /** * @brief 根据名称查找子菜单索引 * @param mainIdx 主菜单索引 * @param name 子菜单名称 * @return 子菜单索引,未找到时返回0 */ size_t findSubIndex(size_t mainIdx, const std::string& name) const; /** * @brief 调整当前子菜单索引 * @note 当主菜单变更时确保子菜单索引有效 */ void adjustSubIndex(); public: /** * @brief 构造函数 * @throw std::invalid_argument 如果目标菜单项无效 */ MenuManager(); /** * @brief 显示当前菜单状态 * @note 清屏后显示主菜单和当前选中的子菜单 */ void displayMenu() const; /** * @brief 检查是否到达目标菜单项 * @return 到达目标返回true,否则false */ bool isTargetReached() const; /** * @brief 获取用户输入 * @param[out] input 存储输入字符 * @return 有输入返回true,无输入返回false * @note Windows使用_kbhit和_getch,Linux/Mac使用select */ bool getInput(char& input); /** * @brief 处理用户输入 * @param input 用户输入字符 */ void handleInput(char input); /** * @brief 运行菜单导航系统 * @note 主循环,显示菜单并处理输入 */ void run(); }; #endif // MENU_SYSTEM_H #include "Menu.h" int main() { MenuManager manager; manager.run(); return 0; } /** * @file Menu.cpp * @brief 菜单导航系统实现文件 * @author huang huan tao * @date 2025/9/28 */ #include "Menu.h" #include <cctype> #include <cmath> // for pow in Linux/Mac // Menu类实现 ===================================================== Menu::Menu(const std::string& mainName, const std::vector<std::string>& subs) : m_mainName(mainName), m_subMenus(subs) { } const std::string& Menu::getMainName() const { return m_mainName; } const std::vector<std::string>& Menu::getSubMenus() const { return m_subMenus; } size_t Menu::getSubMenuCount() const { return m_subMenus.size(); } const std::string& Menu::getSubMenu(size_t index) const { return m_subMenus.at(index < m_subMenus.size() ? index : m_subMenus.size() - 1); } // MenuManager类实现 ============================================== MenuManager::MenuManager() : m_currentMainIndex(0), m_currentSubIndex(1) { m_menus.emplace_back("A", std::vector<std::string>{"A1", "A2", "A3", "A4"}); m_menus.emplace_back("B", std::vector<std::string>{"B1", "B2", "B3"}); m_menus.emplace_back("C", std::vector<std::string>{"C1", "C2", "C3"}); m_menus.emplace_back("D", std::vector<std::string>{"D1", "D2", "D3"}); m_targetMainIndex = findMainIndex("C"); m_targetSubIndex = findSubIndex(m_targetMainIndex, "C3"); // 验证目标菜单项 if (m_targetMainIndex >= m_menus.size() || m_targetSubIndex >= m_menus[m_targetMainIndex].getSubMenuCount()) { } setupNonBlockingInput(); } void MenuManager::clearScreen() const { #ifdef _WIN32 system("cls"); #else system("clear"); #endif } void MenuManager::setupNonBlockingInput() { #ifndef _WIN32 struct termios term; tcgetattr(STDIN_FILENO, &term); term.c_lflag &= ~(ICANON | ECHO); tcsetattr(STDIN_FILENO, TCSANOW, &term); #endif } size_t MenuManager::findMainIndex(const std::string& name) const { for (size_t i = 0; i < m_menus.size(); ++i) { if (m_menus[i].getMainName() == name) return i; } return 0; } size_t MenuManager::findSubIndex(size_t mainIdx, const std::string& name) const { if (mainIdx >= m_menus.size()) return 0; const auto& subs = m_menus[mainIdx].getSubMenus(); for (size_t i = 0; i < subs.size(); ++i) { if (subs[i] == name) return i; } return 0; } void MenuManager::adjustSubIndex() { if (m_currentSubIndex >= m_menus[m_currentMainIndex].getSubMenuCount()) { m_currentSubIndex = m_menus[m_currentMainIndex].getSubMenuCount() - 1; } } void MenuManager::displayMenu() const { clearScreen(); std::cout << "=== 菜单导航系统 ===" << std::endl; std::cout << "操作指南: a/d-切换主菜单 w/s-切换子菜单\n\n"; // 一级菜单 std::cout << "主菜单: "; for (size_t i = 0; i < m_menus.size(); ++i) { if (i == m_currentMainIndex) { std::cout << "[" << m_menus[i].getMainName() << "] "; } else { std::cout << m_menus[i].getMainName() << " "; } } std::cout << "\n\n"; // 二级菜单 const Menu& currentMenu = m_menus[m_currentMainIndex]; std::cout << currentMenu.getMainName() << "的子菜单: "; for (size_t i = 0; i < currentMenu.getSubMenuCount(); ++i) { if (i == m_currentSubIndex) { std::cout << "[" << currentMenu.getSubMenu(i) << "] "; } else { std::cout << currentMenu.getSubMenu(i) << " "; } } // 目标提示 std::cout << "\n\n目标: 选择 " << m_menus[m_targetMainIndex].getMainName() << m_menus[m_targetMainIndex].getSubMenu(m_targetSubIndex) << std::endl; } bool MenuManager::isTargetReached() const { return m_currentMainIndex == m_targetMainIndex && m_currentSubIndex == m_targetSubIndex; } bool MenuManager::getInput(char& input) { #ifdef _WIN32 if (_kbhit()) { input = _getch(); return true; } #else fd_set set; struct timeval tv; FD_ZERO(&set); FD_SET(STDIN_FILENO, &set); tv.tv_sec = 0; tv.tv_usec = 10000; // 10ms超时 if (select(STDIN_FILENO + 1, &set, NULL, NULL, &tv) > 0) { input = getchar(); return true; } #endif return false; } void MenuManager::handleInput(char input) { input = std::tolower(static_cast<unsigned char>(input)); const size_t subCount = m_menus[m_currentMainIndex].getSubMenuCount(); switch (input) { case 'a': // 切换到上一个主菜单 m_currentMainIndex = (m_currentMainIndex + m_menus.size() - 1) % m_menus.size(); adjustSubIndex(); break; case 'd': // 切换到下一个主菜单 m_currentMainIndex = (m_currentMainIndex + 1) % m_menus.size(); adjustSubIndex(); break; case 'w': // 切换到上一个子菜单 m_currentSubIndex = (m_currentSubIndex + subCount - 1) % subCount; break; case 's': // 切换到下一个子菜单 m_currentSubIndex = (m_currentSubIndex + 1) % subCount; break; } } void MenuManager::run() { while (true) { displayMenu(); if (isTargetReached()) { std::cout << "\n成功选择目标菜单! 程序结束" << std::endl; break; } char input = 0; if (getInput(input)) { handleInput(input); } // 降低CPU占用率 #ifdef _WIN32 Sleep(50); #else usleep(50000); #endif } } 解决上述代码中出现的闪屏问题
最新发布
10-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值