次の方法で共有


CMenu::LoadMenuIndirect

更新 : 2007 年 11 月

メモリ上のメニュー テンプレートからリソースを読み込み、CMenu オブジェクトに結び付けます。

BOOL LoadMenuIndirect(
   const void* lpMenuTemplate 
);

パラメータ

  • lpMenuTemplate
    メニュー テンプレートへのポインタ (1 つの MENUITEMTEMPLATEHEADER 構造体と 1 つ以上の MENUITEMTEMPLATE 構造体のコレクションです)。この 2 つの構造体の詳細については、Windows SDK を参照してください。

戻り値

メニュー リソースが正常に読み込まれた場合は 0 以外を返します。それ以外の場合は 0 を返します。

解説

メニュー テンプレートは、ヘッダーと、それに続く 1 つ以上の MENUITEMTEMPLATE 構造体のコレクションからなり、そのそれぞれが 1 つ以上のメニュー項目やポップアップ メニューを持っています。

バージョン番号は 0 であることが必要です。

ポップアップ メニュー リストの最後の項目やメイン リストの最後の項目の mtOption フラグには、MF_END を含むようにしてください。ほかのフラグについては、AppendMenu メンバ関数を参照してください。mtOptionMF_POPUP が指定されたときは、MENUITEMTEMPLATE 構造体から mtId メンバを除外します。

MENUITEMTEMPLATE 構造体のために確保された領域は、NULL で終わる文字列の形式でメニュー項目の名前を mtString に保持するのに十分な大きさを持つ必要があります。

メニューがウィンドウに関連付けられていないときは、アプリケーションが終了する前に、メニューに関連付けられているシステム リソースを解放する必要があります。アプリケーションは、DestroyMenu メンバ関数を使ってメニューを解放します。

使用例

// CMainFrame::OnLoadMenuIndirect() is a menu command handler for 
// CMainFrame class, which in turn is a CFrameWnd-derived class. It 
// shows how to use LoadMenuIndirect() to load a resource from a 
// menu template in memory.
void CMainFrame::OnLoadMenuIndirect() 
{
   // For simplicity, allocate 500 bytes from stack. May use 
   // GlobalAlloc() to allocate memory bytes from heap.
   BYTE milist[500];
   memset(milist, 0, 500);
   int bytes_left = sizeof(milist);

   // Fill up the MENUITEMTEMPLATEHEADER structure.
   MENUITEMTEMPLATEHEADER* mheader = (MENUITEMTEMPLATEHEADER*) milist;
   mheader->versionNumber = 0;
   mheader->offset = 0;

   int bytes_used = sizeof(MENUITEMTEMPLATEHEADER);
   bytes_left -= bytes_used;

   // Add the following menu items to menu bar:
   // File     Edit
   //   Exit     Copy
   //            Paste
   bytes_used += AddMenuItem(milist + bytes_used, bytes_left, L"&File", 0, 
      TRUE, FALSE);
   bytes_left -= bytes_used;
   bytes_used += AddMenuItem(milist + bytes_used, bytes_left, L"E&xit", 
      ID_APP_EXIT, FALSE, TRUE);
   bytes_left -= bytes_used;
   bytes_used += AddMenuItem(milist + bytes_used, bytes_left, L"&Edit", 0, 
      TRUE, TRUE);
   bytes_left -= bytes_used;
   bytes_used += AddMenuItem(milist + bytes_used, bytes_left, L"&Copy", 
      ID_EDIT_COPY, FALSE, FALSE);
   bytes_left -= bytes_used;
   bytes_used += AddMenuItem(milist + bytes_used, bytes_left, L"&Paste", 
      ID_EDIT_PASTE, FALSE, TRUE);
   bytes_left -= bytes_used;

   // Load resource from a menu template in memory.
   ASSERT(m_IndiMenu.LoadMenuIndirect(milist));

   // Remove and destroy old menu
   SetMenu(NULL);
   ::DestroyMenu(m_hMenuDefault);

   // Add new menu.
   SetMenu(&m_IndiMenu);

   // Assign default menu
   m_hMenuDefault = m_IndiMenu.m_hMenu;
}

// This is a helper function for adding a menu item (either a popup 
// or command item) to the specified menu template.
//
//    MenuTemplate  - pointer to a menu template
//    TemplateBytes - space remaining in MenuTemplate
//    MenuString    - string for the menu item to be added
//    MenuID        - id for the command item. Its value is ignored if 
//                    IsPopup is TRUE.
//    IsPopup       - TRUE for popup menu (or submenu); FALSE for command 
//                    item
//    LastItem      - TRUE if MenuString is the last item for the popup; 
//                    FALSE otherwise.
UINT AddMenuItem(LPVOID MenuTemplate, int TemplateBytes, WCHAR* MenuString, 
   WORD MenuID, BOOL IsPopup, BOOL LastItem)
{
   MENUITEMTEMPLATE* mitem = (MENUITEMTEMPLATE*) MenuTemplate;

   UINT  bytes_used = 0;
   if (IsPopup)         // for popup menu
   {      
      if (LastItem)
         mitem->mtOption = MF_POPUP | MF_END;
      else
         mitem->mtOption = MF_POPUP;
      bytes_used += sizeof (mitem->mtOption);  

      mitem = (MENUITEMTEMPLATE*) ((BYTE*) MenuTemplate + bytes_used);
      // a popup doesn't have mtID!!!

      TemplateBytes -= bytes_used;
      wcscpy_s((WCHAR*) mitem, TemplateBytes / sizeof(WCHAR), MenuString);
      bytes_used += (UINT)(sizeof (WCHAR) * (wcslen(MenuString) + 1)); // include '\0'   
   }
   else      // for command item
   {
      mitem->mtOption = LastItem ? MF_END : 0;
      mitem->mtID = MenuID; 
      TemplateBytes -= bytes_used;
      wcscpy_s(mitem->mtString, TemplateBytes / sizeof(WCHAR), MenuString);  
      bytes_used += (UINT)(sizeof (mitem->mtOption ) + sizeof (mitem->mtID) + 
         sizeof (WCHAR) * (wcslen(MenuString) + 1));   // include '\0'
   }

   return bytes_used;
}

必要条件

ヘッダー : afxwin.h

参照

参照

CMenu クラス

階層図

CMenu::DestroyMenu

CMenu::LoadMenu

LoadMenuIndirect

CMenu::AppendMenu

その他の技術情報

CMenu のメンバ