C ++ Владелец Windows нарисовал элемент главного меню ID

Я пытаюсь создать в Windows главное меню, нарисованное владельцем. Я понимаю настройку:

menuiteminfo.ftype = MFT_OWNERDRAW

Я также знаю об обработке сообщений WM_MEASUREITEM и WM_DRAWITEM.

Однако как узнать, какой пункт главного меню отправляет сообщение? (чтобы я мог заполнить соответствующий размер поля и текст) itemID, по-видимому, является единственным уникальным идентификатором. Но как я могу связать этот указатель / дескриптор с рассматриваемым элементом? Я могу использовать lParam, чтобы определить, что это пункт меню. Но я не могу определить, какой пункт меню. GetMenuItemID бесполезен, поскольку он возвращает -1 для всех пунктов главного меню.

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


person anachronon    schedule 01.10.2020    source источник


Ответы (2)


Поле itemID структур MEASUREITEMSTRUCT и DRAWITEMSTRUCT сообщает вам, какой именно пункт меню измеряется / рисуется. Это идентификатор, который вы указываете при создании / изменении пункта меню. Этот идентификатор указывается либо через:

  • параметр uIDNewItem в AppendMenu(), InsertMenu() или ModifyMenu().
  • параметр item InsertMenuItem() или SetMenuItemInfo()
  • поле wID структуры MENUITEMINFO, передаваемой в InsertMenuItem() или SetMenuItemInfo().

Используйте любые идентификаторы, которые вам нужны, если они уникальны для вашего меню.

Вы также можете использовать поле itemData MEASUREITEMSTRUCT и DRAWITEMSTRUCT для получения любых пользовательских данных, которые вы хотите для элементов меню, нарисованных владельцем, если хотите (например, указатель на буфер, содержащий текстовую строку элемента меню). Это настраиваемое значение может быть любым, имеющим для вас значение. Вы устанавливаете это значение в поле dwItemData структуры MENUITEMINFO, которую вы передаете в InsertMenuItem() или SetMenuItemInfo().

Все это описано в документации:

Использование меню: создание Элементы меню, нарисованные владельцем

person Remy Lebeau    schedule 01.10.2020

Спасибо, Реми. Благодаря предметам, которые вы упомянули, и изучению документации по каждому из них я смог найти скрытый секрет. Для элемента главного меню идентификатор элемента как в MEASUREITEMSTRUCT, так и в DRAWITEMSTRUCT является дескриптором раскрывающегося меню этого элемента. Исходя из этого, я добавил эту строку кода в WM_CREATE, чтобы связать идентификатор элемента с числовой (отсчитываемой от нуля) позицией:

mItemID[i] = int(GetSubMenu(hMenu, i));

«i» - это числовая позиция слева направо. Затем я могу использовать такой оператор сравнения в WM_MEASUREITEM и WM_DRAWITEM:

lpmis=(LPMEASUREITEMSTRUCT)lParam; if(lpmis->itemID==mItemID[i])

person anachronon    schedule 02.10.2020