Шаг 567 - CMenu::LoadMenuIndirect.

Автор Каев А. Г.
BOOL LoadMenuIndirect( const void* lpMenuTemplate );

Возвращаемое значение
Отлично от нуля если ресурс меню был загружен успешно, иначе 0.

Параметры
lpMenuTemplate
Укажите на шаблон меню который является одиночной структурой MENUITEMTEMPLATEHEADER и совокупностью одной или большего количества структур MENUITEMTEMPLATE.

Замечания
Загружает ресурс из шаблона меню в памяти и присоединяет его к объекту CMenu. Шаблон меню - верхний колонтитул, сопровождаемый совокупностью одной или большим количеством структур MENUITEMTEMPLATE каждая из которых может содержать один или большее количество пунктов меню и всплывающих меню.
Номер версии должен быть 0.
Флажки mtOption должны включить MF_END для последнего элемента в списке и для последнего элемента в основном списке. См. AppendMenu функцию для других флажков. MtId член должен быть опущен из структуры MENUITEMTEMPLATE когда MF_POPUP определен в mtOption.
Пространство распределенное для структуры MENUITEMTEMPLATE должен быть достаточно большим для mtString, чтобы содержать имя пункта меню как строка с нулевым символом в конце.
Перед выходом, прикладная программа должна освободить ресурсы системы связанные с меню, если меню не назначено к окну. Прикладная программа освобождает меню вызывая DestroyMenu функцию.

Пример

// CMainFrame::OnLoadMenuIndirect()- драйвер команды меню для 
// CMainFrame класса, который в свою очередь является классом потомком CFrameWnd. Это 
// показывает  как использовать LoadMenuIndirect () чтобы загрузить ресурс из  
// шаблона меню в памяти.

void CMainFrame::OnLoadMenuIndirect() 
{
   // Для простоты  распределите 500 байтов в стеке. Можно использовать 
   // GlobalAlloc () чтобы распределить байты памяти в "куче".
   BYTE milist[500];
   memset(milist, 0, 500);

   // Заполнить структуру MENUITEMTEMPLATEHEADER.
   MENUITEMTEMPLATEHEADER* mheader = (MENUITEMTEMPLATEHEADER*) milist;
   mheader->versionNumber = 0;
   mheader->offset = 0;

   int bytes_used = sizeof(MENUITEMTEMPLATEHEADER);

 // Добавить следующие пункты меню:
   // File     Edit
   //   Exit     Copy
   //            Paste
   bytes_used += AddMenuItem(milist + bytes_used, L"&File", 0, TRUE, FALSE);
   bytes_used += AddMenuItem(milist + bytes_used, L"E&xit", ID_APP_EXIT, FALSE, TRUE);
   bytes_used += AddMenuItem(milist + bytes_used, L"&Edit", 0, TRUE, TRUE);
   bytes_used += AddMenuItem(milist + bytes_used, L"&Copy", ID_EDIT_COPY, FALSE, FALSE);
   bytes_used += AddMenuItem(milist + bytes_used, L"&Paste", ID_EDIT_PASTE, FALSE, TRUE);
   
   // Загрузите ресурс  шаблона меню в памяти.
   ASSERT(m_NewMenu.LoadMenuIndirect(milist));

   // Удалите старое меню
   SetMenu(NULL);
   ::DestroyMenu(m_hMenuDefault);

   // Добавьте новое меню
   SetMenu(&m_NewMenu);

   // Установите меню по умолчанию
   m_hMenuDefault = m_NewMenu.m_hMenu;
}

// Это - функция помощника для добавления пункта меню (любое всплывающее 
// или элемент команды) к определенному шаблону меню.
// MenuTemplate - указатель на шаблон меню
// MenuString - строка для пункта меню которая будет добавлена
// MenuID - идентификатор для элемента команды. Значение игнорируется если  IsPopup TRUE.
// IsPopup - TRUE  для всплывающего меню (или под-меню); FALSE для команды 
// LastItem - TRUE если MenuString - последний элемент для всплывающего, FALSE иначе.

UINT AddMenuItem(LPVOID MenuTemplate, WCHAR* MenuString, WORD MenuID, BOOL IsPopup, BOOL LastItem)
{
   MENUITEMTEMPLATE* mitem = (MENUITEMTEMPLATE*) MenuTemplate;

   UINT  bytes_used = 0;
   if (IsPopup)         // для всплывающего меню
   {      
      if (LastItem)
         mitem->mtOption = MF_POPUP | MF_END;
      else
         mitem->mtOption = MF_POPUP;
      bytes_used += sizeof (mitem->mtOption);  
      
      mitem = (MENUITEMTEMPLATE*) ((BYTE*) MenuTemplate + bytes_used);
      // Всплывающее не имеет mtID!!!
      
      wcscpy((WCHAR*) mitem, MenuString);
      bytes_used += sizeof (WCHAR) * (wcslen(MenuString) + 1); // включая'\0'   
   }
   else      // для команд
   {
      mitem->mtOption = LastItem ? MF_END : 0;
      mitem->mtID = MenuID;   
      wcscpy(mitem->mtString, MenuString);  
      bytes_used += sizeof (mitem->mtOption ) + sizeof (mitem->mtID) + 
         sizeof (WCHAR) * (wcslen(MenuString) + 1);   // включая '\0'
   }

   return bytes_used;
}

Hosted by uCoz