`
nathan09
  • 浏览: 145689 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

动态插入子菜单(ID不定)(MFC)

 
阅读更多

Windows 应 用 程 序 的 菜 单 可 以 分 成 两 大 类: 程 序 窗
口 上 方 菜 单 条 上 的 下 拉 式 菜 单 和 可 以 在 任 意 位 置
显 示 的 弹 出 式 菜 单。 用MFC 建 立 下 拉 菜 单 的 方 法 基 本
上 是 相 同 的, 但 建 立 弹 出 式 菜 单 的 方 法 有 很 多。 其
中 较 常 用 的 是:
说 明 一 个CMenu 对 象;

用LoadMenu 成 员 函 数 装 入 菜 单 资 源;

用TrackPopupMenu 在 指 定 位 置 显 示 菜 单 并 发 送 所 选 菜 单 项 的ID;

用DestroyMenu 销 毁 菜 单 释 放 资 源。
---- 在 某 些 应 用 程 序 中, 只 有 在 程 序 运 行 时 才 能 根 据
情 况 确 定 菜 单 项 的 内 容 和 菜 单 项 的 数 目。 这 样 就 无
法 在 编 程 时 建 立 菜 单 资 源, 也 就 不 能 象 上 面 所 述 的 那
样 用LoadMenu 装 入 资 源。 需 要 用 另 一 种 方 法 建 立 菜 单:

说 明 一 个CMenu 对 象;

用CreatePopupMenu 建 立 一 个 空 菜 单, 再 用InsertMenu 或AppendMenu
加 入 菜 单 项;

用TrackPopupMenu 在 指 定 位 置 显 示 菜 单 并 发 送 所 选 菜 单 项 的ID;

用DestroyMenu 销 毁 菜 单 释 放 资 源。
---- 虽 然 这 种 方 法 可 以 动 态 地 建 立 菜 单, 但 是 能 够 向 动
态 菜 单 中 加 入 的 菜 单 项 被 限 制 在 一 个 有 限 的 范 围 内, 并
且 必 须 在 编 程 时 就 确 定 它 们 的ID。 这 是 因 为 按 照MFC 常 规 的
菜 单 处 理 机 制, 每 个 菜 单 项 都 要 有 一 个 处 理 函 数, 用MFC
的 消 息 映 射 使 每 个 菜 单ID 对 应 到 相 应 的 处 理 函 数, 从 而
建 立 菜 单 项 与 处 理 函 数 的 对 应 关 系。 用 户 选 中 某 一 菜 单
项, 就 会 触 发 相 应 的 处 理 函 数。 这 样 一 来, 我 们 必 须 在 编
程 时 就 知 道 所 有 的 菜 单 项, 它 们 的ID 与 对 应 的 处 理 函 数
, 并 用 消 息 映 射 静 态 地 一 一 建 立 对 应 关 系。

---- 在 设 计 程 序 时, 确 实 可 能 出 现 菜 单 项 数 目 无 法 限 制,
菜 单ID 事 先 不 能 确 定 的 情 况。 例 如, 一 个 应 用 程 序 有 两
个 文 档 类A 与B, 每 个 文 档 都 可 以 同 时 打 开 任 意 次。 我 们 希
望 在 一 个 动 态 菜 单 中, 只 列 出 显 示A 类 文 档 的 窗 口 标 题,
另 一 个 动 态 菜 单 中 只 列 出 显 示B 类 文 档 的 窗 口 标 题。 当
选 定 一 个 菜 单 项 时, 对 应 的 文 档 窗 口 显 示 在 最 上 面。 由
于 我 们 不 能 限 制 打 开 的 窗 口 数 目, 也 不 能 预 知 窗 口 标 题,
所 以 就 无 法 确 定 应 该 编 写 多 少 处 理 函 数 以 及 会 有 哪 些 菜
单ID, 当 然 也 就 无 法 用 消 息 映 射 建 立 对 应 关 系。 这 时, 我
们 需 要 一 种 不 使 用 消 息 映 射 的 方 法。 但 是, 不 使 用 消 息 映
射 我 们 如 何 知 道 用 户 选 中 了 哪 一 个 菜 单 项 呢 ? 答 案 是CMenu
类 的 成 员 函 数TrackPopupMenu 可 以 告 诉 我 们。
我 们 可 以 从 手 册 或 联 机 帮 助 中 找 到 关 于 该 函 数 的 介 绍:


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

---- 参 数nFlag 用 于 指 定 弹 出 式 菜 单 的 位 置 标 志 与 有 效 鼠 标 键。
可 以 取 的 值 为 下 列 的 一 个 或 多 个:


TPM_CENTERALIGN,TPM_LEFTALIGN,TPM_RIGHTALIGN,
TPM_LEFTBUTTON,TPM_RIGHTBUTTON

---- 参 数x,y 为 弹 出 式 菜 单 的 位 置, 参 数pWnd 为 父 窗 口 指 针。

---- 该 函 数 在 指 定 位 置 显 示 一 个 弹 出 式 菜 单, 并 发 送 以 选 中
菜 单 项ID 标 识 的 消 息。 执 行 成 功 返 回 非 零 值, 否 则 返 回 零。

---- 这 并 不 是 关 于TrackPopupMenu 的 全 部 信 息。 该 函 数 至 少 有 两
个 重 要 特 性 没 有 列 入 文 档, 而 它 们 对 于 解 决 我 们 的 问 题 是
至 关 重 要 的。 第 一 个 未 写 入 文 档 的 特 性 是: 该 函 数 的 第 一
个 参 数nFlag 还 可 以 取 另 外 两 个 值:TPM_ NONOTIFY 与TPM_RETURNCMD。
从 它 们 的 名 字 可 以 看 出 来,TPM_ NONOTIFY 的 作 用 是 使TrackPopupMenu 函
数 不 发 送 菜 单 消 息 通 知 应 用 程 序。TPM_RETURNCMD 的 作 用 是 使 函 数
将 本 该 发 送 出 去 的 菜 单 消 息 作 为 返 回 值 返 回。 这 时 函 数 的 返
回 值 是UINT 类 型 的, 就 是 选 中 的 菜 单ID。 这 就 是 该 函 数 第 二 个
未 写 入 文 档 的 特 性


---- 下 面, 我 们 通 过 一 个 例 子 详 细 解 释TrackPopupMenu 的 这 种 用
法。

voidCreateDynamicMenu()
...{
CPointpt;
GetCursorPos(
&pt);

CMenum_NewMenu;
m_NewMenu.LoadMenu(IDR_MENU_POPUP);
//顶级菜单,事先在资源管理器中建好

CMenu
*pM=m_NewMenu.GetSubMenu(0);//一级下拉菜单

CMenu
*pSubmenu=pM->GetSubMenu(pM->GetMenuItemCount()-1);//二级子菜单
ASSERT(pSubmenu);

UINTnEnable
=MF_BYPOSITION|MF_STRING|MF_ENABLED;
for(...)...{
pSubmenu
->InsertMenu(pSubmenu->GetMenuItemCount()-1,nEnable,(UINT_PTR)ID,菜单文字);
}


intSelectID=(HTREEITEM)pM->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL|
TPM_NONOTIFY
|TPM_RETURNCMD,pt.x,pt.y,this);

//根据获得的ID作出相应的动作
}
该函数一般在右键消息处理函数中调用.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics