WINAPI, удалить всплывающее меню из меню - PullRequest
2 голосов
/ 04 ноября 2019

Я хотел бы иметь динамическое меню в моем приложении. Это динамическое меню должно содержать всплывающие меню, которые будут добавлены и удалены на лету. Для первого подхода я создал динамическое меню, созданное из отдельных пунктов меню.

AppendMenu(menu, MF_STRING, item_id, "TEST");

Я создал алгоритм, который генерирует item_id и сохраняет их в массиве, чтобы я мог удалить их с помощью

DeleteMenu(menu, id_to_be_deleted, MF_BYCOMMAND);

Я не вижу никаких подводных камней в этой реализации, и я доволен этим. Но потом застрял с окончательной реализацией. Я хотел бы, чтобы мои меню были всплывающими меню.

new_popup_menu = CreatePopupMenu();
AppendMenu(new_popup_menu, MF_STRING, 1, "TEST1");
AppendMenu(new_popup_menu, MF_STRING, 2, "TEST2");
AppendMenu(new_popup_menu, MF_STRING, 3, "TEST3");
AppendMenu(menu, MF_STRING|MF_POPUP, 
          (UINT_PTR)new_popup_menu, "dynamic menu");

Этот код работает, как и ожидалось, но я понятия не имею, как удалить "new_popup_menu" из "меню", так как параметр "UINT_PTR uIDNewItem" в AppendMenu теперьиспользуется в качестве дескриптора подменю, а не ID и не может использоваться с DeleteMenu + MF_BYCOMMAND. Есть ли способ удалить этот элемент подменю, кроме DeleteMenu + MF_BYPOSITION? Есть ли способ получить положение пункта меню по дескриптору, который возвращается CreatePopupMenu ())? Я чувствую реализацию алгоритма слежения за тем, какое меню в какой позиции вызывает боль в заднице. Поскольку в Windows есть API для вставки меню после другого определенного меню, воссоздание всего дерева меню является пустой тратой процессорного времени.

1 Ответ

0 голосов
/ 05 ноября 2019

Если вы хотите создать пункт меню, который открывает подменю и имеет идентификатор, создайте его с помощью InsertMenuItem(...) вместо AppendMenu(...). InsertMenuItem(...) позволяет вам заполнить структуру, которая задает все свойства, которые вы хотите установить в элементе меню, который вы создаете, включая ID и подменю. Многие Win32 работают таким образом: AppendMenu(...) - это сокращенная версия для более подробной версии той же функции. Когда вы сталкиваетесь с ситуациями, когда вы не можете сделать что-то разумное с определенным вызовом Win32, ищите синонимный вызов, который принимает структуру * INFO.

Код ниже:

...
HMENU menu_bar = GetMenu(hWnd);
HMENU new_menu = CreateMenu();
AppendMenu(menu_bar, MF_POPUP, (UINT_PTR)new_menu, "foobar");
AppendMenu(new_menu, MF_ENABLED | MF_STRING, 1002, "item1");
AppendMenu(new_menu, MF_ENABLED | MF_STRING, 1003, "item2");

HMENU dynamic_popup = CreatePopupMenu();
AppendMenu(dynamic_popup, MF_ENABLED | MF_STRING, 1004, "mumble");
AppendMenu(dynamic_popup, MF_ENABLED | MF_STRING, 1005, "quux");

// Below will add an item named "dynamic menu" to the end of new_menu
// that has an ID of 1006.

MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU | MIIM_STRING | MIIM_ID;
mii.dwTypeData = (LPSTR)"dynamic menu";
mii.hSubMenu = dynamic_popup;
mii.wID = 1006;
InsertMenuItem(new_menu, 0, FALSE, &mii);

//DeleteMenu(new_menu, 1006, MF_BYCOMMAND);
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...