| 22 | } |
| 23 | |
| 24 | wil::unique_hmenu BaseContextMenu::BuildContextMenuInner(const wfc::IVector<wuxc::MenuFlyoutItemBase> &items) |
| 25 | { |
| 26 | wil::unique_hmenu menu(CreatePopupMenu()); |
| 27 | if (menu) |
| 28 | { |
| 29 | UINT position = 0; |
| 30 | for (const wuxc::MenuFlyoutItemBase item : items) |
| 31 | { |
| 32 | if (item.Visibility() != wux::Visibility::Visible) |
| 33 | { |
| 34 | continue; |
| 35 | } |
| 36 | |
| 37 | wil::unique_hmenu subMenu; |
| 38 | winrt::hstring menuText; |
| 39 | MENUITEMINFO itemInfo = { |
| 40 | .cbSize = sizeof(itemInfo) |
| 41 | }; |
| 42 | |
| 43 | if (const auto menuItem = item.try_as<wuxc::MenuFlyoutItem>()) |
| 44 | { |
| 45 | // keep a reference alive for dwItemData |
| 46 | m_Items.insert(menuItem); |
| 47 | menuText = menuItem.Text(); |
| 48 | |
| 49 | itemInfo.fMask = MIIM_DATA | MIIM_ID | MIIM_STATE | MIIM_STRING; |
| 50 | itemInfo.fState = menuItem.IsEnabled() ? MFS_ENABLED : MFS_DISABLED; |
| 51 | itemInfo.wID = GetNextClickableId(); |
| 52 | itemInfo.dwTypeData = const_cast<wchar_t *>(menuText.c_str()); |
| 53 | itemInfo.dwItemData = reinterpret_cast<ULONG_PTR>(winrt::get_abi(menuItem)); |
| 54 | |
| 55 | if (const auto radioItem = menuItem.try_as<muxc::RadioMenuFlyoutItem>()) |
| 56 | { |
| 57 | itemInfo.fState |= radioItem.IsChecked() ? MFS_CHECKED : MFS_UNCHECKED; |
| 58 | itemInfo.fMask |= MIIM_FTYPE; |
| 59 | itemInfo.fType = MFT_RADIOCHECK; |
| 60 | } |
| 61 | else if (const auto toggleItem = menuItem.try_as<wuxc::ToggleMenuFlyoutItem>()) |
| 62 | { |
| 63 | itemInfo.fState |= toggleItem.IsChecked() ? MFS_CHECKED : MFS_UNCHECKED; |
| 64 | } |
| 65 | } |
| 66 | else if (const auto subItem = item.try_as<wuxc::MenuFlyoutSubItem>()) |
| 67 | { |
| 68 | subMenu = BuildContextMenuInner(subItem.Items()); |
| 69 | menuText = subItem.Text(); |
| 70 | |
| 71 | itemInfo.fMask = MIIM_STATE | MIIM_STRING | MIIM_SUBMENU; |
| 72 | itemInfo.fState = subItem.IsEnabled() ? MFS_ENABLED : MFS_DISABLED; |
| 73 | itemInfo.hSubMenu = subMenu.get(); |
| 74 | itemInfo.dwTypeData = const_cast<wchar_t *>(menuText.c_str()); |
| 75 | } |
| 76 | else if (const auto separator = item.try_as<wuxc::MenuFlyoutSeparator>()) |
| 77 | { |
| 78 | itemInfo.fMask = MIIM_FTYPE; |
| 79 | itemInfo.fType = MFT_SEPARATOR; |
| 80 | } |
| 81 | else |