CMenu

封装 Windows HMENU

语法

class CMenu : public CObject

成员

公共构造函数

名称 描述
CMenu::CMenu 构造 CMenu 对象。

公共方法

名称 描述
CMenu::AppendMenu 将新项追加到此菜单的末尾。
CMenu::Attach 将 Windows 菜单句柄附加到 CMenu 对象。
CMenu::CheckMenuItem 在弹出菜单中的菜单项旁放置复选标记或删除复选标记。
CMenu::CheckMenuRadioItem 在某个菜单项旁放置单选按钮,并删除组中所有其他菜单项的单选按钮。
CMenu::CreateMenu 创建一个空菜单并将其附加到 CMenu 对象。
CMenu::CreatePopupMenu 创建一个弹出菜单并将其附加到 CMenu 对象。
CMenu::DeleteMenu 从菜单中删除指定的项。 如果菜单项具有关联的弹出菜单,则销毁弹出菜单的句柄,并释放其使用的内存。
CMenu::DeleteTempMap 删除 FromHandle 成员函数创建的任何暂时性 CMenu 对象。
CMenu::DestroyMenu 销毁附加到 CMenu 对象的菜单,并释放菜单占用的任何内存。
CMenu::Detach CMenu 对象分离 Windows 菜单句柄并返回该句柄。
CMenu::DrawItem 当所有者绘制菜单的可视方面发生变化时由框架调用。
CMenu::EnableMenuItem 启用、禁用菜单项或使菜单项变暗(灰显)。
CMenu::FromHandle 在给定 Windows 菜单句柄的情况下,返回指向 CMenu 对象的指针。
CMenu::GetDefaultItem 确定指定菜单上的默认菜单项。
CMenu::GetMenuContextHelpId 检索与菜单关联的帮助上下文 ID。
CMenu::GetMenuInfo 检索特定菜单上的信息。
CMenu::GetMenuItemCount 确定弹出菜单或顶级菜单中的项数。
CMenu::GetMenuItemID 获取位于指定位置的菜单项的菜单项标识符。
CMenu::GetMenuItemInfo 检索有关菜单项的信息。
CMenu::GetMenuState 返回指定菜单项的状态或弹出菜单中的项数。
CMenu::GetMenuString 检索指定菜单项的标签。
CMenu::GetSafeHmenu 返回此 CMenu 对象包装的 m_hMenu
CMenu::GetSubMenu 检索指向弹出菜单的指针。
CMenu::InsertMenu 在指定位置插入新菜单项,并将其他项向下移动。
CMenu::InsertMenuItem 在菜单中的指定位置插入新菜单项。
CMenu::LoadMenu 从可执行文件加载菜单资源并将其附加到 CMenu 对象。
CMenu::LoadMenuIndirect 从内存中的菜单模板加载菜单并将其附加到 CMenu 对象。
CMenu::MeasureItem 由框架调用,用于确定创建所有者绘制的菜单时的菜单维度。
CMenu::ModifyMenu 更改位于指定位置的现有菜单项。
CMenu::RemoveMenu 从指定菜单中删除具有关联弹出菜单的菜单项。
CMenu::SetDefaultItem 设置指定的菜单的默认菜单项。
CMenu::SetMenuContextHelpId 设置要与菜单关联的帮助上下文 ID。
CMenu::SetMenuInfo 设置特定菜单上的信息。
CMenu::SetMenuItemBitmaps 将指定的复选标记位图与菜单项相关联。
CMenu::SetMenuItemInfo 更改有关菜单项的信息。
CMenu::TrackPopupMenu 在指定位置显示浮动弹出菜单,并跟踪弹出菜单上项的选择情况。
CMenu::TrackPopupMenuEx 在指定位置显示浮动弹出菜单,并跟踪弹出菜单上项的选择情况。

公共运算符

“属性” 描述
CMenu::operator HMENU 检索菜单对象的句柄。
CMenu::operator != 确定两个菜单对象是否不相等。
CMenu::operator == 确定两个菜单对象是否相等。

公共数据成员

“属性” 描述
CMenu::m_hMenu 指定附加到 CMenu 对象的 Windows 菜单的句柄。

备注

它提供用于创建、跟踪、更新和销毁菜单的成员函数。

在堆栈帧上创建一个 CMenu 对象作为本地对象,然后调用 CMenu 的成员函数以根据需要操作新菜单。 接下来,调用 CWnd::SetMenu 将菜单设置为窗口,然后立即调用 CMenu 对象的 Detach 成员函数。 成员 CWnd::SetMenu 函数将窗口的菜单设置为新菜单,导致为反映菜单更改而重新绘制窗口,并将菜单的所有权传递给窗口。 对 Detach 的调用将 HMENUCMenu 对象分离,这样,当局部 CMenu 变量的传递超出范围时,CMenu 目标析构函数不会尝试销毁它不再拥有的菜单。 当窗口被销毁时,会自动销毁菜单。

可以使用 LoadMenuIndirect 成员函数从内存中的模板创建菜单,但通过调用 LoadMenu 从资源创建的菜单更易于维护,菜单资源本身可由菜单编辑器创建和修改。

继承层次结构

CObject

CMenu

要求

标头afxwin.h

CMenu::AppendMenu

将新项追加到菜单末尾。

BOOL AppendMenu(
    UINT nFlags,
    UINT_PTR nIDNewItem = 0,
    LPCTSTR lpszNewItem = NULL);

BOOL AppendMenu(
    UINT nFlags,
    UINT_PTR nIDNewItem,
    const CBitmap* pBmp);

参数

nFlags
指定在将新菜单项添加到菜单时该项的状态的相关信息。 它包含“备注”部分中列出的一个或多个值。

nIDNewItem
指定新菜单项的命令 ID,或如果 nFlags 设置为 MF_POPUP,则指定弹出菜单的菜单句柄 (HMENU)。 如果 nFlags 设置为 MF_SEPARATOR,则忽略 nIDNewItem 参数(不需要)。

lpszNewItem
指定新菜单项的内容。 nFlags 参数用于按以下方式解释 lpszNewItem

nFlags 解释 lpszNewItem
MF_OWNERDRAW 包含应用程序提供的 32 位值,应用程序可使用该值维护与菜单项关联的其他数据。 当应用程序处理 WM_MEASUREITEMWM_DRAWITEM 消息时,应用程序可使用此 32 位值。 该值存储在随这些消息一起提供的结构的 itemData 成员中。
MF_STRING 包含指向以 null 结尾的字符串的指针。 这是默认解释。
MF_SEPARATOR 将忽略 lpszNewItem 参数(不需要)。

pBmp
指向将用作菜单项的 CBitmap 对象。

返回值

如果该函数成功,则为非 0;否则为 0。

注解

应用程序可以通过在 nFlags 中设置值来指定菜单项的状态。 当 nIDNewItem 指定一个弹出菜单时,它将成为所附加菜单的一部分。 如果该菜单被销毁,附加菜单也将被销毁。 附加菜单应与 CMenu 对象分离以避免冲突。 请注意,MF_STRINGMF_OWNERDRAWAppendMenu 的位图版本无效。

以下列表描述了 nFlags 中可能设置的标志:

  • MF_CHECKED 充当使用 MF_UNCHECKED 的转换,将默认复选标记放置在项旁边。 当应用程序提供复选标记位图时(参见 SetMenuItemBitmaps 成员函数),将显示“复选标记打开”位图。

  • MF_UNCHECKED 充当使用 MF_CHECKED 的转换,删除项目旁边的复选标记。 当应用程序提供复选标记位图时(参见 SetMenuItemBitmaps 成员函数),将显示“复选标记关闭”位图。

  • MF_DISABLED 禁用菜单项,使其无法被选中,但不将其灰显。

  • MF_ENABLED 启用菜单项,使其可被选中,并消除其灰显状态。

  • MF_GRAYED 禁用菜单项,使其无法被选中,同时将其灰显。

  • MF_MENUBARBREAK 将项目放置在静态菜单中的新行上或弹出菜单中的新列中。 将使用垂直分隔线将新弹出菜单列与旧列隔开。

  • MF_MENUBREAK 将项目放置在静态菜单中的新行上或弹出菜单中的新列中。 列之间无分隔线。

  • MF_OWNERDRAW 指定该项是所有者绘制项。 第一次显示菜单时,拥有菜单的窗口将收到一条 WM_MEASUREITEM 消息,该消息检索菜单项的高度和宽度。 每当所有者需要更新菜单项的视觉外观时,都会发送 WM_DRAWITEM 消息。 此选项对顶级菜单项无效。

  • MF_POPUP 指定菜单项具有与其关联的弹出菜单。 ID 参数指定要与项关联的弹出菜单的句柄。 这用于将顶级弹出菜单或分层弹出菜单添加到弹出菜单项。

  • MF_SEPARATOR 绘制一条水平分割线。 只能在弹出菜单中使用。 此线条不能灰显、禁用或突出显示。 将忽略其他参数。

  • MF_STRING 指定菜单项为字符串。

以下每个组列出了相互排斥、不能一起使用的标志:

  • MF_DISABLEDMF_ENABLEDMF_GRAYED

  • MF_STRINGMF_OWNERDRAWMF_SEPARATOR 和位图版本

  • MF_MENUBARBREAKMF_MENUBREAK

  • MF_CHECKEDMF_UNCHECKED

每当窗口中的菜单发生更改时(无论是否显示该窗口),应用程序都应调用 CWnd::DrawMenuBar

示例

请参阅 CMenu::CreateMenu 的示例。

CMenu::Attach

将现有 Windows 菜单附加到 CMenu 对象。

BOOL Attach(HMENU hMenu);

参数

hMenu
指定 Windows 菜单的句柄。

返回值

如果操作成功,则为非零;否则为 0。

备注

如果已有菜单附加到 CMenu 对象,则不应调用此函数。 菜单句柄存储在 m_hMenu 数据成员中。

如果要操纵的菜单已与窗口关联,则可以使用 CWnd::GetMenu 函数获取菜单句柄。

示例

CMenu mnu;
HMENU hmnu = AfxGetMainWnd()->GetMenu()->GetSafeHmenu();
mnu.Attach(hmnu);

// Now you can manipulate the window's menu as a CMenu
// object...

mnu.Detach();

CMenu::CheckMenuItem

向弹出菜单中的菜单项添加复选标记或从其删除复选标记。

UINT CheckMenuItem(
    UINT nIDCheckItem,
    UINT nCheck);

参数

nIDCheckItem
指定要检查的菜单项,由 nCheck 确定。

nCheck
指定如何检查菜单项以及如何确定该项在菜单中的位置。 nCheck 参数可以是 MF_CHECKEDMF_UNCHECKEDMF_BYPOSITIONMF_BYCOMMAND 标志的组合。 可以使用按位 OR 运算符组合这些标志。 它们具有以下含义:

  • MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 这是默认情况。

  • MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

  • MF_CHECKED 充当使用 MF_UNCHECKED 的转换,将默认复选标记放置在项旁边。

  • MF_UNCHECKED 充当使用 MF_CHECKED 的转换,删除项目旁边的复选标记。

返回值

项的先前状态:MF_CHECKEDMF_UNCHECKED,或 0xFFFFFFFF(如果菜单项不存在)。

注解

nIDCheckItem 参数指定要修改的项。

nIDCheckItem 参数可标识弹出菜单项以及菜单项。 检查弹出菜单项时无需特殊步骤。 无法选中顶级菜单项。 必须按位置检查弹出菜单项,因为它没有与之关联的菜单项标识符。

示例

请参阅 CMenu::GetMenuState 的示例。

CMenu::CheckMenuRadioItem

检查指定的菜单项并使其成为单选项。

BOOL CheckMenuRadioItem(
    UINT nIDFirst,
    UINT nIDLast,
    UINT nIDItem,
    UINT nFlags);

参数

nIDFirst
指定单选按钮组中的第一个菜单项(作为 ID 或偏移量,具体取决于 nFlags 的值)。

nIDLast
指定单选按钮组中的最后一个菜单项(作为 ID 或偏移量,具体取决于 nFlags 的值)。

nIDItem
指定组中将使用单选按钮勾选的项(作为 ID 或偏移量,取决于 nFlags 的值)。

nFlags
按以下方式指定对 nIDFirstnIDLastnIDItem 的解释:

nFlags 解释
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

返回值

如果成功,则为非零;否则为 0

备注

同时,该函数取消选中关联组中的所有其他菜单项,并清除这些项的单选项类型标志。 使用单选按钮(或项目符号)位图而不是复选标记位图显示选中的项。

示例

请参阅 ON_COMMAND_RANGE 的示例。

CMenu::CMenu

创建一个空菜单并将其附加到 CMenu 对象。

CMenu();

备注

在调用 CMenu 的创建或加载成员函数之前,不会创建菜单:

CMenu::CreateMenu

创建菜单并将其附加到 CMenu 对象。

BOOL CreateMenu();

返回值

如果菜单创建成功,则为非零;否则为 0。

注解

菜单最初为空。 可以使用 AppendMenuInsertMenu 成员函数添加菜单项。

如果将菜单指定给窗口,则在窗口被销毁时将自动销毁该菜单。

退出之前,如果某菜单未分配给窗口,则应用程序必须释放与该菜单关联的系统资源。 应用程序通过调用 DestroyMenu 成员函数释放菜单。

示例

// The code fragment below shows how to create a new menu for the
// application window using CreateMenu() and CreatePopupMenu().
// Then, the created menu will replace the current menu of the
// application. The old menu will be destroyed with DestroyMenu().
// NOTE: The code fragment below is done in a CFrameWnd-derived class.

// Create a new menu for the application window.
VERIFY(m_NewMenu.CreateMenu());

// Create a "File" popup menu and insert this popup menu to the
// new menu of the application window. The "File" menu has only
// one menu item, i.e. "Exit".
VERIFY(m_FileMenu.CreatePopupMenu());
m_FileMenu.AppendMenu(MF_STRING, ID_APP_EXIT, _T("E&xit"));
m_NewMenu.AppendMenu(MF_POPUP, (UINT_PTR)m_FileMenu.m_hMenu, _T("&File"));

// Remove and destroy old menu
SetMenu(NULL);
CMenu *old_menu = CMenu::FromHandle(m_hMenuDefault);
old_menu->DestroyMenu();

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

// Assign default menu
m_hMenuDefault = m_NewMenu.m_hMenu;

CMenu::CreatePopupMenu

创建弹出菜单并将其附加到 CMenu 对象。

BOOL CreatePopupMenu();

返回值

如果弹出菜单成功创建,则为非零;否则为 0。

备注

菜单最初为空。 可以使用 AppendMenuInsertMenu 成员函数添加菜单项。 应用程序可以将弹出菜单添加到现有菜单或弹出菜单。 TrackPopupMenu 成员函数可用于将此菜单显示为浮动弹出菜单,并跟踪弹出菜单上的选择情况。

如果将菜单指定给窗口,则在窗口被销毁时将自动销毁该菜单。 如果将菜单添加到某现有菜单,则当该现有菜单被销毁时,会自动销毁该菜单。

在退出之前,如果未将某个弹出菜单分配给窗口,应用程序需要释放与该菜单关联的系统资源。 应用程序通过调用 DestroyMenu 成员函数释放菜单。

示例

请参阅 CMenu::CreateMenu 的示例。

CMenu::DeleteMenu

从菜单中删除项。

BOOL DeleteMenu(
    UINT nPosition,
    UINT nFlags);

参数

nPosition
指定要删除的菜单项,由 nFlags 确定。

nFlags
用于按以下方式解释 nPosition

nFlags 解释 nPosition
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

返回值

如果该函数成功,则为非 0;否则为 0。

备注

如果菜单项具有关联的弹出菜单,则 DeleteMenu 销毁弹出菜单的句柄,并释放其使用的内存。

每当窗口中的菜单发生更改时(无论是否显示该窗口),应用程序都必须调用 CWnd::DrawMenuBar

示例

请参阅 CWnd::GetMenu 的示例。

CMenu::DeleteTempMap

CWinApp 空闲时间处理程序自动调用,删除任何由 FromHandle 成员函数创建的临时 CMenu 对象。

static void PASCAL DeleteTempMap();

备注

在删除 CMenu 对象之前,DeleteTempMap 会分离附加到临时 CMenu 对象的 Windows 菜单对象。

示例

// DeleteTempMap() is a static member and does not need
// an instantiated CMenu object.
CMenu::DeleteTempMap();

CMenu::DestroyMenu

销毁菜单和所有已使用的 Windows 资源。

BOOL DestroyMenu();

返回值

如果菜单被销毁,则为非零;否则为 0。

注解

在销毁 CMenu 对象之前,会将菜单与该对象分离。 将在 CMenu 析构函数中自动调用 Windows DestroyMenu 函数。

示例

请参阅 CMenu::CreateMenu 的示例。

CMenu::Detach

CMenu 对象分离 Windows 菜单并返回句柄。

HMENU Detach();

返回值

如果成功,则为指向 Windows 菜单的 HMENU 类型句柄;否则为 NULL

备注

m_hMenu 数据成员设置为 NULL

示例

CMenu mnu;
HMENU hmnu = AfxGetMainWnd()->GetMenu()->GetSafeHmenu();
mnu.Attach(hmnu);

// Now you can manipulate the window's menu as a CMenu
// object...

mnu.Detach();

CMenu::DrawItem

当所有者绘制菜单的可视方面发生变化时由框架调用。

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

参数

lpDrawItemStruct
指向 DRAWITEMSTRUCT 结构的指针,其中包含有关所需绘制类型的信息。

备注

DRAWITEMSTRUCT 结构的 itemAction 成员定义要执行的绘制操作。 替代此成员函数以实现所有者绘制 CMenu 对象的绘制。 在终止此成员函数之前,应用程序应还原为 lpDrawItemStruct 中提供的显示上下文选择的所有图形设备接口 (GDI) 对象。

请参阅 CWnd::OnDrawItem 查看有关 DRAWITEMSTRUCT 结构的说明。

示例

以下代码来自 MFC CTRLTEST 示例:

// Override DrawItem() to implement drawing for an owner-draw CMenu object.
// CColorMenu is a CMenu-derived class.
void CColorMenu::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
   CDC *pDC = CDC::FromHandle(lpDIS->hDC);
   COLORREF cr = (COLORREF)lpDIS->itemData; // RGB in item data

   if (lpDIS->itemAction & ODA_DRAWENTIRE)
   {
      // Paint the color item in the color requested
      CBrush br(cr);
      pDC->FillRect(&lpDIS->rcItem, &br);
   }

   if ((lpDIS->itemState & ODS_SELECTED) &&
       (lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
   {
      // item has been selected - hilite frame
      COLORREF crHilite = RGB(255 - GetRValue(cr),
                              255 - GetGValue(cr), 255 - GetBValue(cr));
      CBrush br(crHilite);
      pDC->FrameRect(&lpDIS->rcItem, &br);
   }

   if (!(lpDIS->itemState & ODS_SELECTED) &&
       (lpDIS->itemAction & ODA_SELECT))
   {
      // Item has been de-selected -- remove frame
      CBrush br(cr);
      pDC->FrameRect(&lpDIS->rcItem, &br);
   }
}

CMenu::EnableMenuItem

启用、禁用或灰显菜单项。

UINT EnableMenuItem(
    UINT nIDEnableItem,
    UINT nEnable);

参数

nIDEnableItem
指定要启用的菜单项,由 nEnable 确定。 此参数可以指定弹出菜单项以及标准菜单项。

nEnable
指定要执行的操作。 它可以是 MF_DISABLEDMF_ENABLEDMF_GRAYEDMF_BYCOMMANDMF_BYPOSITION 的组合。 可以使用 C++ 按位 OR 运算符 (|) 组合这些值。 这些值将具有以下含义:

  • MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 这是默认情况。

  • MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

  • MF_DISABLED 禁用菜单项,使其无法被选中,但不将其灰显。

  • MF_ENABLED 启用菜单项,使其可被选中,并消除其灰显状态。

  • MF_GRAYED 禁用菜单项,使其无法被选中,同时将其灰显。

返回值

以前的状态(MF_DISABLEDMF_ENABLEDMF_GRAYED)或 -1(如果无效)。

备注

CreateMenuInsertMenuModifyMenuLoadMenuIndirect 成员函数还可以设置菜单项的状态(启用、禁用或灰显)。

使用 MF_BYPOSITION 值需要应用程序使用正确的 CMenu。 如果使用菜单栏的 CMenu,顶级菜单项(菜单栏中的项目)将受到影响。 要按位置设置弹出菜单或嵌套弹出菜单中项目的状态,应用程序必须指定弹出菜单的 CMenu

当应用程序指定 MF_BYCOMMAND 标志时,Windows 将检查从属于 CMenu 的所有弹出菜单项;因此,除非存在重复的菜单项,否则使用菜单栏的 CMenu 就足够了。

示例

// The code fragment below shows how to disable (and gray out) the
// File\New menu item.
// NOTE: m_bAutoMenuEnable is set to FALSE in the constructor of
// CMainFrame so no ON_UPDATE_COMMAND_UI or ON_COMMAND handlers are
// needed, and CMenu::EnableMenuItem() will work as expected.

CMenu *mmenu = GetMenu();
CMenu *submenu = mmenu->GetSubMenu(0);
submenu->EnableMenuItem(ID_FILE_NEW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);

CMenu::FromHandle

返回指向给定的 Windows 菜单句柄的 CMenu 对象的指针。

static CMenu* PASCAL FromHandle(HMENU hMenu);

参数

hMenu
菜单的 Windows 句柄。

返回值

指向 CMenu 的指针,该指针可以是临时的,也可以是永久的。

备注

如果尚未有 CMenu 对象附加到 Windows 菜单对象,会创建并附加一个临时 CMenu 对象。

此临时 CMenu 对象仅在应用程序下次在其事件循环中有空闲时间之前有效,那时所有临时对象都将被删除。

示例

请参阅 CMenu::CreateMenu 的示例。

CMenu::GetDefaultItem

确定指定菜单上的默认菜单项。

UINT GetDefaultItem(
    UINT gmdiFlags,
    BOOL fByPos = FALSE);

参数

gmdiFlags
指定函数如何搜索菜单项的值。 此参数可以是“无”、“一”或以下值的组合:

含义
GMDI_GOINTOPOPUPS 指定如果默认项是打开子菜单的项,则函数将以递归方式在相应的子菜单中搜索。 如果子菜单没有默认项,则由返回值来标识打开子菜单的项。

默认情况下,该函数返回指定菜单上的第一个默认项,不管该项是否是打开子菜单的项。
GMDI_USEDISABLED 指定函数要返回默认项,即使该项已禁用。

默认情况下,该函数会跳过禁用或灰显项。

fByPos
用于指定是检索菜单项的标识符还是其位置的值。 如果此参数为 FALSE,则返回标识符。 否则,返回位置。

返回值

如果函数成功,返回值是菜单项的标识符或位置。 如果函数失败,返回值为 -1。

备注

此成员函数实现 Win32 函数 GetMenuDefaultItem 的行为,如 Windows SDK 中所述。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::GetMenuContextHelpId

检索与 CMenu 关联的上下文帮助 ID。

DWORD GetMenuContextHelpId() const;

返回值

当前与 CMenu 关联的上下文帮助 ID(如果有);否则为零。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::GetMenuInfo

检索菜单的信息。

BOOL GetMenuInfo(LPMENUINFO lpcmi) const;

参数

lpcmi
指向包含菜单信息的 MENUINFO 结构的指针。

返回值

如果函数成功,则返回值为非零;否则,返回值为零。

备注

调用此函数可检索有关菜单的信息。

CMenu::GetMenuItemCount

确定弹出菜单或顶级菜单中的项数。

UINT GetMenuItemCount() const;

返回值

如果函数成功,则为菜单中的项数;否则为 -1。

示例

请参阅 CWnd::GetMenu 的示例。

CMenu::GetMenuItemID

获取位于 nPos 定义的位置的菜单项的菜单项标识符。

UINT GetMenuItemID(int nPos) const;

参数

nPos
指定要检索其 ID 的菜单项的位置(从零开始)。

返回值

如果函数成功,则为弹出菜单中指定的项的项 ID。 如果指定的项是弹出菜单(不是弹出菜单中的项),则返回值为 -1。 如果 nPos 对应于 SEPARATOR 菜单项,则返回值为 0。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::GetMenuItemInfo

检索有关菜单项的信息。

BOOL GetMenuItemInfo(
    UINT uItem,
    LPMENUITEMINFO lpMenuItemInfo,
    BOOL fByPos = FALSE);

参数

uItem
要获取其信息的菜单项的标识符或位置。 此参数的含义取决于 ByPos 的值。

lpMenuItemInfo
指向 MENUITEMINFO 的指针,如 Windows SDK 中所述,其中包含有关菜单的信息。

fByPos
用于指定 nIDItem 含义的值。 默认情况下,ByPosFALSE,这表示 uItem 是菜单项标识符。 如果 ByPos 未设置为 FALSE,则表示菜单项的位置。

返回值

如果该函数成功,则返回值为非零值。 如果函数失败,则返回值为零。 若要获取扩展错误信息,使用 Win32 函数 GetLastError,如 Windows SDK 中所述。

备注

此成员函数实现 Win32 函数 GetMenuItemInfo 的行为,如 Windows SDK 中所述。 请注意,在 GetMenuItemInfo 的 MFC 实现中,不使用菜单句柄。

示例

// CMainFrame::OnToggleTestMenuInfo() is a menu command handler for 
// "Toggle Info" menu item (whose resource id is ID_MENU_TOGGLEINFO). It 
// toggles the checked or unchecked state of the "Toggle Info" menu item.
// CMainFrame is a CFrameWnd-derived class.
void CMainFrame::OnToggleTestMenuItemInfo()
{
   // Get the popup menu which contains the "Toggle Info" menu item.
   CMenu* mmenu = GetMenu();
   CMenu* submenu = mmenu->GetSubMenu(4);

   // Check the state of the "Toggle Info" menu item. Check the menu item
   // if it is currently unchecked. Otherwise, uncheck the menu item
   // if it is not currently checked.
   MENUITEMINFO info;
   info.cbSize = sizeof (MENUITEMINFO); // must fill up this field
   info.fMask = MIIM_STATE;             // get the state of the menu item
   VERIFY(submenu->GetMenuItemInfo(ID_MENU_TOGGLEINFO, &info));

   if (info.fState & MF_CHECKED)
      submenu->CheckMenuItem(ID_MENU_TOGGLEINFO, MF_UNCHECKED | MF_BYCOMMAND);
   else
      submenu->CheckMenuItem(ID_MENU_TOGGLEINFO, MF_CHECKED | MF_BYCOMMAND);
}

CMenu::GetMenuState

返回指定菜单项的状态或弹出菜单中的项数。

UINT GetMenuState(
    UINT nID,
    UINT nFlags) const;

参数

nID
指定由 nFlags 确定的菜单项 ID。

nFlags
指定 nID 的性质。 可以为下列值之一:

  • MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 这是默认值。

  • MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

返回值

如果指定的项不存在,则为值 0xFFFFFFFF。 如果 nId 标识弹出菜单,则高位字节包含弹出菜单中的项数,低位字节包含与弹出菜单相关联的菜单标志。 否则,返回值是以下列表中值的掩码(布尔 OR)(此掩码描述 nId 标识的菜单项的状态):

  • MF_CHECKED 充当使用 MF_UNCHECKED 的转换,将默认复选标记放置在项旁边。 当应用程序提供复选标记位图时(参见 SetMenuItemBitmaps 成员函数),将显示“复选标记打开”位图。

  • MF_DISABLED 禁用菜单项,使其无法被选中,但不将其灰显。

  • MF_ENABLED 启用菜单项,使其可被选中,并消除其灰显状态。 注意,该常数的值为 0;当使用此值时,应用程序不应针对 0 测试失败结果。

  • MF_GRAYED 禁用菜单项,使其无法被选中,同时将其灰显。

  • MF_MENUBARBREAK 将项目放置在静态菜单中的新行上或弹出菜单中的新列中。 将使用垂直分隔线将新弹出菜单列与旧列隔开。

  • MF_MENUBREAK 将项目放置在静态菜单中的新行上或弹出菜单中的新列中。 列之间无分隔线。

  • MF_SEPARATOR 绘制一条水平分割线。 只能在弹出菜单中使用。 此线条不能灰显、禁用或突出显示。 将忽略其他参数。

  • MF_UNCHECKED 充当使用 MF_CHECKED 的转换,删除项目旁边的复选标记。 当应用程序提供复选标记位图时(参见 SetMenuItemBitmaps 成员函数),将显示“复选标记关闭”位图。 注意,该常数的值为 0;当使用此值时,应用程序不应针对 0 测试失败结果。

示例

// CMainFrame::OnToggleTestMenuState() is a menu command handler for
// "Toggle State" menu item (whose resource id is ID_MENU_TOGGLESTATE).
// It toggles the checked or unchecked state of the "Toggle State" menu item.
// CMainFrame is a CFrameWnd-derived class.
void CMainFrame::OnToggleTestMenuState()
{
   // Get the popup menu which contains the "Toggle State" menu item.
   CMenu *mmenu = GetMenu();
   CMenu *submenu = mmenu->GetSubMenu(4);

   // Check the state of the "Toggle State" menu item. Check the menu item
   // if it is currently unchecked. Otherwise, uncheck the menu item
   // if it is not currently checked.
   UINT state = submenu->GetMenuState(ID_MENU_TOGGLESTATE, MF_BYCOMMAND);
   ASSERT(state != 0xFFFFFFFF);

   if (state & MF_CHECKED)
      submenu->CheckMenuItem(ID_MENU_TOGGLESTATE, MF_UNCHECKED | MF_BYCOMMAND);
   else
      submenu->CheckMenuItem(ID_MENU_TOGGLESTATE, MF_CHECKED | MF_BYCOMMAND);
}

CMenu::GetMenuString

将指定菜单项的标签复制到指定缓冲区。

int GetMenuString(
    UINT nIDItem,
    LPTSTR lpString,
    int nMaxCount,
    UINT nFlags) const;

int GetMenuString(
    UINT nIDItem,
    CString& rString,
    UINT nFlags) const;

参数

nIDItem
根据 nFlags 的值,指定菜单项的整数标识符或菜单项在菜单中的偏移量。

lpString
指向要接收标签的缓冲区。

rString
CString 对象的引用,该对象将接收复制的菜单字符串。

nMaxCount
指定要复制的标签的最大长度(以字符为单位)。 如果标签长度超过 nMaxCount 中指定的最大值,会截断超出的字符。

nFlags
指定 nIDItem 参数的解释。 可以为下列值之一:

nFlags 解释 nIDItem
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

返回值

指定复制到缓冲区的实际字符数,不包括空终止符。

备注

nMaxCount 参数应大于标签中的字符数,以容纳字符串结尾的 null 字符。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::GetSafeHmenu

返回此 CMenu 对象包装的 HMENU,或 NULLCMenu 指针。

HMENU GetSafeHmenu() const;

示例

请参阅 CMenu::LoadMenu 的示例。

CMenu::GetSubMenu

检索弹出菜单的 CMenu 对象。

CMenu* GetSubMenu(int nPos) const;

参数

nPos
指定菜单中包含的弹出菜单的位置。 第一个菜单项的位置值从 0 开始。 此函数中不能使用弹出菜单的标识符。

返回值

指向 CMenu 对象的指针,该对象的 m_hMenu 成员包含弹出菜单的句柄(如果在给定位置存在弹出菜单);否则为 NULL。 如果 CMenu 对象不存在,则会创建一个临时对象。 不应存储返回的 CMenu 指针。

示例

请参阅 CMenu::TrackPopupMenu 的示例。

CMenu::InsertMenu

nPosition 指定的位置插入新菜单项,并向下移动菜单中的其他项。

BOOL InsertMenu(
    UINT nPosition,
    UINT nFlags,
    UINT_PTR nIDNewItem = 0,
    LPCTSTR lpszNewItem = NULL);

BOOL InsertMenu(
    UINT nPosition,
    UINT nFlags,
    UINT_PTR nIDNewItem,
    const CBitmap* pBmp);

参数

nPosition
指定要在其前插入新菜单项的菜单项。 nFlags 参数可用于按以下方式解释 nPosition

nFlags 解释 nPosition
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。 如果 nPosition 为 -1,则新菜单项将附加到菜单的末尾。

nFlags
指定如何解释 nPosition,并指定新菜单项添加到菜单时的状态信息。 有关可设置的标志列表,请参阅 AppendMenu 成员函数。 要指定多个值,使用按位 OR 运算符将它们与 MF_BYCOMMANDMF_BYPOSITION 标志组合。

nIDNewItem
指定新菜单项的命令 ID,或如果 nFlags 设置为 MF_POPUP,则指定弹出菜单的菜单句柄 (HMENU)。 如果 nFlags 设置为 MF_SEPARATOR,则忽略 nIDNewItem 参数(不需要)。

lpszNewItem
指定新菜单项的内容。 nFlags 可用于按以下方式解释 lpszNewItem

nFlags 解释 lpszNewItem
MF_OWNERDRAW 包含应用程序提供的 32 位值,应用程序可使用该值维护与菜单项关联的其他数据。 可在 WM_MEASUREITEMWM_DRAWITEM 消息提供的结构的 itemData 成员中将此 32 位值提供给应用程序使用。 这些消息在菜单项最初显示或更改时发送。
MF_STRING 包含指向以 null 结尾的字符串的长指针。 这是默认解释。
MF_SEPARATOR 将忽略 lpszNewItem 参数(不需要)。

pBmp
指向将用作菜单项的 CBitmap 对象。

返回值

如果该函数成功,则为非 0;否则为 0。

备注

应用程序可以通过在 nFlags 中设置值来指定菜单项的状态。

每当窗口中的菜单发生更改时(无论是否显示该窗口),应用程序都应调用 CWnd::DrawMenuBar

nIDNewItem 指定弹出菜单时,它将成为其插入的菜单的一部分。 如果该菜单被销毁,则插入的菜单也将被销毁。 插入的菜单应与 CMenu 对象分离以避免冲突。

如果激活的多文档界面 (MDI) 子窗口为最大化状态,并且应用程序通过调用此函数并指定 MF_BYPOSITION 标志将弹出菜单插入 MDI 应用程序的菜单中,则菜单将插入到比预期更靠左的位置。 这是因为活动 MDI 子窗口的控制菜单插入到了 MDI 框架窗口菜单栏的第一个位置。 若要正确定位菜单,应用程序必须将其他情况下使用的位置值增加 1。 应用程序可以使用 WM_MDIGETACTIVE 消息来决定是否将当前活动的子窗口最大化。

示例

// CMainFrame::OnChangeFileMenu() is a menu command handler for
// CMainFrame class, which in turn is a CFrameWnd-derived class.
// It modifies the File menu by inserting, removing and renaming
// some menu items. Other operations include associating a context
// help id and setting default menu item to the File menu.
// CMainFrame is a CFrameWnd-derived class.
void CMainFrame::OnChangeFileMenu()
{
   // Get the menu from the application window.
   CMenu *mmenu = GetMenu();

   // Look for "File" menu.
   int pos = FindMenuItem(mmenu, _T("&File"));
   if (pos == -1)
      return;

   // Remove "New" menu item from the File menu.
   CMenu *submenu = mmenu->GetSubMenu(pos);
   pos = FindMenuItem(submenu, _T("&New\tCtrl+N"));
   if (pos > -1)
      submenu->RemoveMenu(pos, MF_BYPOSITION);

   // Look for "Open" menu item from the File menu. Insert a new
   // menu item called "Close" right after the "Open" menu item.
   // ID_CLOSEFILE is the command id for the "Close" menu item.
   pos = FindMenuItem(submenu, _T("&Open...\tCtrl+O"));
   if (pos > -1)
      submenu->InsertMenu(pos + 1, MF_BYPOSITION, ID_CLOSEFILE, _T("&Close"));

   // Rename menu item "Exit" to "Exit Application".
   pos = FindMenuItem(submenu, _T("E&xit"));
   if (pos > -1)
   {
      UINT id = submenu->GetMenuItemID(pos);
      submenu->ModifyMenu(id, MF_BYCOMMAND, id, _T("E&xit Application"));
   }

   // Associate a context help ID with File menu, if one is not found.
   // ID_FILE_CONTEXT_HELPID is the context help ID for the File menu
   // that is defined in resource file.
   if (submenu->GetMenuContextHelpId() == 0)
      submenu->SetMenuContextHelpId(ID_FILE_CONTEXT_HELPID);

   // Set "Open" menu item as the default menu item for the File menu,
   // if one is not found. So, when a user double-clicks the File
   // menu, the system sends a command message to the menu's owner
   // window and closes the menu as if the File\Open command item had
   // been chosen.
   if (submenu->GetDefaultItem(GMDI_GOINTOPOPUPS, TRUE) == -1)
   {
      pos = FindMenuItem(submenu, _T("&Open...\tCtrl+O"));
      submenu->SetDefaultItem(pos, TRUE);
   }
}

// FindMenuItem() will find a menu item string from the specified
// popup menu and returns its position (0-based) in the specified
// popup menu. It returns -1 if no such menu item string is found.
int FindMenuItem(CMenu *Menu, LPCTSTR MenuString)
{
   ASSERT(Menu);
   ASSERT(::IsMenu(Menu->GetSafeHmenu()));

   int count = Menu->GetMenuItemCount();
   for (int i = 0; i < count; i++)
   {
      CString str;
      if (Menu->GetMenuString(i, str, MF_BYPOSITION) &&
          str.Compare(MenuString) == 0)
         return i;
   }

   return -1;
}

CMenu::InsertMenuItem

在菜单中的指定位置插入新菜单项。

BOOL InsertMenuItem(
    UINT uItem,
    LPMENUITEMINFO lpMenuItemInfo,
    BOOL fByPos = FALSE);

参数

uItem
请参阅 Windows SDK 中 InsertMenuItem 中的 uItem 的说明。

lpMenuItemInfo
请参阅 Windows SDK 中 InsertMenuItem 中的 lpmii 的说明。

fByPos
请参阅 Windows SDK 中 InsertMenuItem 中的 fByPosition 的说明。

注解

此函数包装 InsertMenuItem,如 Windows SDK 中所述。

CMenu::LoadMenu

从应用程序的可执行文件加载菜单资源,并将其附加到 CMenu 对象。

BOOL LoadMenu(LPCTSTR lpszResourceName);
BOOL LoadMenu(UINT nIDResource);

参数

lpszResourceName
指向以 null 结尾的字符串,该字符串包含要加载的菜单资源的名称。

nIDResource
指定要加载的菜单资源的菜单 ID。

返回值

如果菜单资源加载成功,则为非零;否则为 0。

备注

退出之前,如果某菜单未分配给窗口,则应用程序必须释放与该菜单关联的系统资源。 应用程序通过调用 DestroyMenu 成员函数释放菜单。

示例

// CMainFrame::OnReplaceMenu() is a menu command handler for CMainFrame
// class, which in turn is a CFrameWnd-derived class. It loads a new
// menu resource and replaces the SDI application window's menu bar with
// this new menu. CMainFrame is a CFrameWnd-derived class.
void CMainFrame::OnReplaceMenu()
{
   // Load the new menu.
   m_ShortMenu.LoadMenu(IDR_SHORT_MENU);
   ASSERT(m_ShortMenu);

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

   // Add the new menu
   SetMenu(&m_ShortMenu);

   // Assign default menu
   m_hMenuDefault = m_ShortMenu.GetSafeHmenu(); // or m_ShortMenu.m_hMenu;
}

CMenu::LoadMenuIndirect

从内存中的菜单模板加载资源,并将其附加到 CMenu 对象。

BOOL LoadMenuIndirect(const void* lpMenuTemplate);

参数

lpMenuTemplate
指向菜单模板(它是单个 MENUITEMTEMPLATEHEADER 结构和一个或多个 MENUITEMTEMPLATE 架构的集合)。 有关这两种结构的更多信息,请参阅 Windows SDK。

返回值

如果菜单资源加载成功,则为非零;否则为 0。

备注

菜单模板是一个标头后跟一个或多个 MENUITEMTEMPLATE 结构的集合,其中每个结构可能包含一个或更多菜单项和弹出菜单。

版本号应为 0。

mtOption 标志应包括用于弹出列表中最后一项和主列表中最后一项的 MF_END。 请参阅 AppendMenu 成员函数,查看其他标志。 当 mtOption 中指定了 MF_POPUP 时,必须从 MENUITEMTEMPLATE 结构中省略 mtId 成员。

MENUITEMTEMPLATE 结构分配的空间必须足够大,以便 mtString 能够将菜单项的名称按以 null 结尾的字符串形式包含在内。

退出之前,如果某菜单未分配给窗口,则应用程序必须释放与该菜单关联的系统资源。 应用程序通过调用 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;
}

CMenu::m_hMenu

指定附加到 CMenu 对象的 Windows 菜单的 HMENU 句柄。

HMENU m_hMenu;

示例

请参阅 CMenu::LoadMenu 的示例。

CMenu::MeasureItem

当创建具有所有者绘制样式的菜单时由框架调用。

virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

参数

lpMeasureItemStruct
指向 MEASUREITEMSTRUCT 结构的指针。

备注

默认情况下,此成员函数不执行任何操作。 重写此成员函数并填写 MEASUREITEMSTRUCT 结构以向 Windows 通知菜单的尺寸。

请参阅 CWnd::OnMeasureItem 查看有关 MEASUREITEMSTRUCT 结构的说明。

示例

以下代码来自 MFC CTRLTEST 示例:

// Override MeasureItem() to return the size of the menu item.
// CColorMenu is a CMenu-derived class.

#define COLOR_BOX_WIDTH 20
#define COLOR_BOX_HEIGHT 20

void CColorMenu::MeasureItem(LPMEASUREITEMSTRUCT lpMIS)
{
   // all items are of fixed size
   lpMIS->itemWidth = COLOR_BOX_WIDTH;
   lpMIS->itemHeight = COLOR_BOX_HEIGHT;
}

CMenu::ModifyMenu

nPosition 指定的位置更改现有菜单项。

BOOL ModifyMenu(
    UINT nPosition,
    UINT nFlags,
    UINT_PTR nIDNewItem = 0,
    LPCTSTR lpszNewItem = NULL);

BOOL ModifyMenu(
    UINT nPosition,
    UINT nFlags,
    UINT_PTR nIDNewItem,
    const CBitmap* pBmp);

参数

nPosition
指定要更改的菜单项。 nFlags 参数可用于按以下方式解释 nPosition

nFlags 解释 nPosition
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

nFlags
指定如何解释 nPosition,并提供有关对菜单项所做更改的信息。 有关可设置的标志的列表,请参阅 AppendMenu 成员函数。

nIDNewItem
指定修改后的菜单项的命令 ID,或如果 nFlags 设置为 MF_POPUP,则指定弹出菜单的菜单句柄 (HMENU)。 如果 nFlags 设置为 MF_SEPARATOR,则忽略 nIDNewItem 参数(不需要)。

lpszNewItem
指定新菜单项的内容。 nFlags 参数可用于按以下方式解释 lpszNewItem

nFlags 解释 lpszNewItem
MF_OWNERDRAW 包含应用程序提供的 32 位值,应用程序可使用该值维护与菜单项关联的其他数据。 此 32 位值在应用程序处理 MF_MEASUREITEMMF_DRAWITEM 时可用于应用程序。
MF_STRING 包含指向以 null 结尾的字符串或 CString 的长指针。
MF_SEPARATOR 将忽略 lpszNewItem 参数(不需要)。

pBmp
指向将用作菜单项的 CBitmap 对象。

返回值

如果该函数成功,则为非 0;否则为 0。

备注

应用程序通过设置 nFlags 中的值来指定菜单项的新状态。 如果此函数要替换与菜单项关联的弹出菜单,会销毁旧的弹出菜单并释放该弹出菜单使用的内存。

nIDNewItem 指定弹出菜单时,它将成为其插入的菜单的一部分。 如果该菜单被销毁,则插入的菜单也将被销毁。 插入的菜单应与 CMenu 对象分离以避免冲突。

每当窗口中的菜单发生更改时(无论是否显示该窗口),应用程序都应调用 CWnd::DrawMenuBar。 要更改现有菜单项的属性,使用 CheckMenuItemEnableMenuItem 成员函数要快得多。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::operator HMENU

使用此运算符可检索 CMenu 对象的句柄。

operator HMENU() const;

返回值

如果成功,则为 CMenu 对象的句柄;否则为 NULL

备注

可以使用句柄直接调用 Windows API。

CMenu::operator !=

确定两个菜单在逻辑上是否不相等。

BOOL operator!=(const CMenu& menu) const;

参数

menu
一个用于比较的 CMenu 对象。

备注

测试左侧的菜单对象是否不等于右侧的菜单对象。

CMenu::operator ==

确定两个菜单在逻辑上是否相等。

BOOL operator==(const CMenu& menu) const;

参数

menu
一个用于比较的 CMenu 对象。

备注

测试左侧的菜单对象是否等于右侧的菜单对象(根据 HMENU 值)。

CMenu::RemoveMenu

从菜单中删除具有关联弹出菜单的菜单项。

BOOL RemoveMenu(
    UINT nPosition,
    UINT nFlags);

参数

nPosition
指定要删除的菜单项。 nFlags 参数可用于按以下方式解释 nPosition

nFlags 解释 nPosition
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

nFlags
指定如何解释 nPosition

返回值

如果该函数成功,则为非 0;否则为 0。

备注

它不会销毁弹出菜单的句柄,因此可以重用该菜单。 在调用此函数之前,应用程序可以调用 GetSubMenu 成员函数来检索弹出 CMenu 对象以供重复使用。

每当窗口中的菜单发生更改时(无论是否显示该窗口),应用程序都必须调用 CWnd::DrawMenuBar

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::SetDefaultItem

设置指定的菜单的默认菜单项。

BOOL SetDefaultItem(
    UINT uItem,
    BOOL fByPos = FALSE);

参数

uItem
新的默认菜单项的标识符或位置,或如果为 -1,则表示无默认项。 此参数的含义取决于 fByPos 的值。

fByPos
用于指定 uItem 含义的值。 如果此参数为 FALSEuItem 为菜单项标识符。 否则,它是菜单项位置。

返回值

如果该函数成功,则返回值为非零值。 如果函数失败,则返回值为零。 若要获取扩展错误信息,使用 Win32 函数 GetLastError,如 Windows SDK 中所述。

备注

此成员函数实现 Win32 函数 SetMenuDefaultItem 的行为,如 Windows SDK 中所述。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::SetMenuContextHelpId

将上下文帮助 ID 与 CMenu 关联。

BOOL SetMenuContextHelpId(DWORD dwContextHelpId);

参数

dwContextHelpId
要与 CMenu 关联的上下文帮助 ID。

返回值

如果成功,则为非零;否则为 0

注解

菜单中的所有项都共享此标识符 - 不可能将帮助上下文标识符附加到单个菜单项。

示例

请参阅 CMenu::InsertMenu 的示例。

CMenu::SetMenuInfo

设置菜单的信息。

BOOL SetMenuInfo(LPCMENUINFO lpcmi);

参数

lpcmi
指向包含菜单信息的 MENUINFO 结构的指针。

返回值

如果函数成功,则返回值为非零;否则,返回值为零。

备注

调用此函数可设置有关菜单的特定信息。

CMenu::SetMenuItemBitmaps

将指定的位图与菜单项相关联。

BOOL SetMenuItemBitmaps(
    UINT nPosition,
    UINT nFlags,
    const CBitmap* pBmpUnchecked,
    const CBitmap* pBmpChecked);

参数

nPosition
指定要更改的菜单项。 nFlags 参数可用于按以下方式解释 nPosition

nFlags nPosition 的解释
MF_BYCOMMAND 指定该参数提供现有菜单项的命令 ID。 如果既未设置 MF_BYCOMMAND 也未设置 MF_BYPOSITION,则这是默认值。
MF_BYPOSITION 指定该参数提供现有菜单项的位置。 第一项位于位置 0。

nFlags
指定如何解释 nPosition

pBmpUnchecked
指定要用于未选中的菜单项的位图。

pBmpChecked
指定要用于选中的菜单项的位图。

返回值

如果该函数成功,则为非 0;否则为 0。

备注

无论菜单项被选中还是未被选中,Windows 都在菜单项旁显示相应位图。

如果 pBmpUncheckedpBmpCheckedNULL,Windows 在相应特性的菜单项旁边不会显示任何内容。 如果两个参数均为 NULL,则 Windows 在项目被选中时应用默认复选标记,在项目被取消选中时删除复选标记。

当菜单被销毁时,这些位图不会被销毁;应用程序必须将其销毁。

Windows GetMenuCheckMarkDimensions 函数检索用于菜单项的默认复选标记的维度。 应用程序使用这些值来确定此函数提供的位图的适当大小。 获取大小,创建位图,然后进行设置。

示例

// The code fragment below is from CMainFrame::OnCreate and shows
// how to associate bitmaps with the "Bitmap" menu item.
// Whether the "Bitmap" menu item is checked or unchecked, Windows
// displays the appropriate bitmap next to the menu item. Both
// IDB_CHECKBITMAP and IDB_UNCHECKBITMAP bitmaps are loaded
// in OnCreate() and destroyed in the destructor of CMainFrame class.
// CMainFrame is a CFrameWnd-derived class.

// Load bitmaps from resource. Both m_CheckBitmap and m_UnCheckBitmap
// are member variables of CMainFrame class of type CBitmap.
ASSERT(m_CheckBitmap.LoadBitmap(IDB_CHECKBITMAP));
ASSERT(m_UnCheckBitmap.LoadBitmap(IDB_UNCHECKBITMAP));

// Associate bitmaps with the "Bitmap" menu item.
CMenu *mmenu = GetMenu();
CMenu *submenu = mmenu->GetSubMenu(4);
ASSERT(submenu->SetMenuItemBitmaps(ID_MENU_BITMAP, MF_BYCOMMAND,
                                   &m_CheckBitmap, &m_UnCheckBitmap));

 

// This code fragment is taken from CMainFrame::~CMainFrame

// Destroy the bitmap objects if they are loaded successfully
// in OnCreate().
if (m_CheckBitmap.m_hObject)
   m_CheckBitmap.DeleteObject();

if (m_UnCheckBitmap.m_hObject)
   m_UnCheckBitmap.DeleteObject();

CMenu::SetMenuItemInfo

更改有关菜单项的信息。

BOOL SetMenuItemInfo(
    UINT uItem,
    LPMENUITEMINFO lpMenuItemInfo,
    BOOL fByPos = FALSE);

参数

uItem
请参阅 Windows SDK 中 SetMenuItemInfo 中的 uItem 的说明。

lpMenuItemInfo
请参阅 Windows SDK 中 SetMenuItemInfo 中的 lpmii 的说明。

fByPos
请参阅 Windows SDK 中 SetMenuItemInfo 中的 fByPosition 的说明。

注解

此函数包装 SetMenuItemInfo,如 Windows SDK 中所述。

CMenu::TrackPopupMenu

在指定位置显示浮动弹出菜单,并跟踪弹出菜单上项的选择情况。

BOOL TrackPopupMenu(
    UINT nFlags,
    int x,
    int y,
    CWnd* pWnd,
    LPCRECT lpRect = 0);

参数

nFlags
指定屏幕位置和鼠标位置标志。 有关可用标志的列表,请参见 TrackPopupMenu

x
以弹出菜单的屏幕坐标指定水平位置。 根据 nFlags 参数的值,菜单可以相对于该位置左对齐、右对齐或居中。

y
以菜单顶部在屏幕上的屏幕坐标指定垂直位置。

pWnd
标识拥有弹出菜单的窗口。 即使指定了 TPM_NONOTIFY 标志,此参数也不能为 NULL。 此窗口接收来自菜单的所有 WM_COMMAND 消息。 在 Windows 3.1 版及更高版本中,在 TrackPopupMenu 返回之前,窗口不会接收 WM_COMMAND 消息。 在 Windows 3.0 中,窗口在 TrackPopupMenu 返回之前接收 WM_COMMAND 消息。

lpRect
已忽略。

返回值

此方法返回在 Windows SDK 中调用 TrackPopupMenu 时的结果。

备注

浮动弹出菜单可以出现在屏幕上的任何位置。

示例

// The code fragment shows how to get the File menu from the
// application window and displays it as a floating popup menu
// when the right mouse button is clicked in view.
// CMdiView is a CView-derived class.
void CMdiView::OnRButtonDown(UINT nFlags, CPoint point)
{
   CView::OnRButtonDown(nFlags, point);

   CMenu *menu_bar = AfxGetMainWnd()->GetMenu();
   CMenu *file_menu = menu_bar->GetSubMenu(0);
   ASSERT(file_menu);

   ClientToScreen(&point);
   file_menu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x,
                             point.y, this);
}

CMenu::TrackPopupMenuEx

在指定位置显示浮动弹出菜单,并跟踪弹出菜单上项的选择情况。

BOOL TrackPopupMenuEx(
    UINT fuFlags,
    int x,
    int y,
    CWnd* pWnd,
    LPTPMPARAMS lptpm);

参数

fuFlags
指定扩展菜单的各种功能。 有关所有值及其含义的列表,请参见 TrackPopupMenuEx

x
以弹出菜单的屏幕坐标指定水平位置。

y
以菜单顶部在屏幕上的屏幕坐标指定垂直位置。

pWnd
指向拥有弹出菜单并从创建的菜单接收消息的窗口的指针。 此窗口可以是当前应用程序中的任何窗口,但不能是 NULL。 如果在 fuFlags 参数中指定 TPM_NONOTIFY,则函数不会向 pWnd 发送任何消息。 函数必须针对 pWnd 指向的窗口返回,才能接收 WM_COMMAND 消息。

lptpm
指向 TPMPARAMS 结构的指针,该结构指定菜单不能重叠的屏幕区域。 此参数可以为 NULL

返回值

如果在 fuFlags 参数中指定 TPM_RETURNCMD,则返回值是用户选择的项的菜单项标识符。 如果用户在不选择的情况下取消菜单,或发生了错误,则返回 0。

如果未在参数 fuFlags 中指定 TPM_RETURNCMD,则如果函数成功,则返回非零值;如果函数失败,则返回 0。 若要获得扩展的错误信息,请调用 GetLastError

备注

浮动弹出菜单可以出现在屏幕上的任何位置。 有关创建弹出菜单时处理错误的详细信息,请参见 TrackPopupMenuEx

另请参阅

MFC 示例 CTRLTEST
MFC 示例 DYNAMENU
CObject
层次结构图