Я немного поработал с winapi, создавая проект, в котором владелец использовал меню. Когда я позвонил GetMenuItemInfo
, он устанавливает текст пункта меню, но не флаги переменной UINT fType.
В настоящее время я заявил:
MenuItem->fMask = MIIM_TYPE
И MSDN говорит:
MIIM_TYPE Retrieves or sets the fType and dwTypeData members.
Я не знаю, запутался ли я с флагом MIIM_TYPE.
Вот мой код:
void SetOwnerDrawMenu(HMENU * menu)
{
MENUIF * menu_item_information;
HMENU sub_menu_ocational;
UINT uId_menuitem;
int nMenuCountItems = GetMenuItemCount(*menu);
MENUITEMINFO * MenuItem = (MENUITEMINFO*)malloc(sizeof(MENUITEMINFO));
for(int i=0;i<nMenuCountItems;i++)
{
menu_item_information = (MENUIF*)malloc(sizeof(MENUIF));
menu_item_information->isSeparator=false;
menu_item_information->max_width=0;
sub_menu_ocational = 0;
uId_menuitem = GetMenuItemID(*menu,i);
memset(&MenuItem,0,sizeof(MenuItem));
MenuItem = (MENUITEMINFO*)malloc(sizeof(MENUITEMINFO));
MenuItem->cbSize = sizeof(MenuItem);
MenuItem->fMask = MIIM_TYPE;
MenuItem->cch = MAX_ODM_CCH;
MenuItem->dwTypeData = menu_item_information->szItemText;
GetMenuItemInfo(*menu,uId_menuitem,FALSE,MenuItem);
UINT final_flags = MF_BYPOSITION | MF_OWNERDRAW;
if( ( MFT_SEPARATOR & MenuItem->fType ) == MFT_SEPARATOR )
{
final_flags |= MF_SEPARATOR;
menu_item_information->isSeparator = true;
}
else
{
// Not important stuff
}
sub_menu_ocational = GetSubMenu(*menu,i);
if(sub_menu_ocational!=NULL)
{
ModifyMenu(*menu,i,final_flags,0,(LPCTSTR)menu_item_information);
// We got a submenu, repeat this operation
SetOwnerDrawMenu(&sub_menu_ocational);
}
else
{
ModifyMenu(*menu,i,final_flags,0,(LPCTSTR)menu_item_information);
}
}
}
Я вставляю меню с InsertMenu
функция:
InsertMenu(tid_cmenu,0,MF_BYPOSITION | MF_SEPARATOR,0,NULL);
InsertMenu(tid_cmenu,0, MF_BYPOSITION | MF_STRING, TID_EXIT, "Exit");
Точно, почему GetMenuItemInfo
не восстанавливает fType?
Если вы проверяли код возврата от GetMenuItemInfo
вы бы увидели, что это терпит неудачу. Ваша ошибка в этой строке:
MenuItem->cbSize = sizeof(MenuItem);
MENUITEMINFO::cbSize
элемент должен быть установлен в размере MENUITEMINFO
структура, но вы устанавливаете его в размере MENUITEMINFO*
указатель (то есть 4 или 8 байтов, в зависимости от платформы).
Измените свой код на:
MenuItem->cbSize = sizeof(MENUITEMINFO);
Кроме того, ваш код выделяет MenuItem
вне цикла, а также один раз за итерацию внутри цикла, так что вы теряете память.
Хорошо. Проблема не в синтаксисе и не в размере памяти.
Это больше похоже на «логическую» ошибку и глупую ошибку.
ModifyMenu
менял все пункты меню и
установив fType каждого из них в NULL или установив MF_SEPARATOR для всех элементов.
Это произошло потому, что четвертый аргумент ModifyMenu
должен быть идентификатор пункта меню, я объявил его как 0.
Я изменил этот аргумент на реальный идентификатор пункта меню, используя GetMenuItemID
возвращаемое значение внутри uId_menuitem
переменная и передавая ее четвертому аргументу ModifyMenu
, Это решило проблему.
Спасибо!