分享
 
 
 

利 用MFC 的 消 息 映 像 实 现 动 态 菜 单

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

---- 当 我 们 提 到 动 态 菜 单 的 实 现 时, 我 们 通 常 的 做 法 是 使 用GetMenu() 函 数 获 取 一 个Cmenu 类 指 针, 然 后 调 用CMenu 类 方 法AppendMenu, InsertMenu, ModifyMenu, RemoveMenu 等。 本 文 介 绍 一 种 更 加 简 洁 的 方 法, 它 利 用MFC 的 消 息 映 像 机 制 及CCmdUI 类 方 法 来 实 现。

---- 首 先, 我 们 简 要 说 说VC 中MFC 的 消 息 映 像。 每 个Windows 程 序 员 大 概 都 对 以 前 使 用 的 窗 口 函 数WindowProc 记 忆 犹 新, 当 我 们 面 对 各 种 消 息 时, 我 们 别 无 他 方, 只 能 使 用 庞 大 而 机 械 的switch-case 语 句 来 实 现 不 同 的 分 支 选 择。 在VC5.0 中 使 用V4.2 版 的MFC 基 本 类 库, 你 将 告 别switch-case 语 句, 代 之 以 透 明 的 消 息 映 像。 要 在 一 个 类 中 使 用 消 息 映 像, 在 类 声 明 中, 必 须 显 式 的 加 入 宏DECLARE_MESSAGE_MAP:

class CMyClass: public CBaseClass

{

DECLARE_MESSAGE_MAP()

}

---- 在 类 实 现 中, 必 须 使 用 两 个 宏BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP,BEGIN_MESSAGE_MAP 带 两 个 参 数: 当 前 类 和 直 接 父 类:

---- BEGIN_MESSAGE_MAP(CMyClass, CBaseClass)

---- // 消 息 映 像 项

---- ON_COMMAND(ID_APP_ABOUT, OnAppAbout)

---- // 消 息 映 像 项

---- END_MESSAGE_MAP()

---- 消 息 映 像 项 使 用 下 列 基 本 语 法:

---- ON_MessageName(ID, ClassMethod)

---- MessageName 是 需 要 处 理 的 消 息,ID 是 发 送 消 息 的 标 识 符, 而ClassMethod 为 处 理 此 消 息 的 类 方 法 名。MessageName 是MFC 预 定 义 的, 可 分 为 以 下 三 种:

---- 命 令 消 息

---- 子 窗 口 通 知 消 息

---- Windows 消 息

---- 共 一 百 多 个, 用 户 不 必 记 住 它 们, 因 为 消 息 映 像 可 以 很 简 单 的 利 用ClassWizard 加 入。 处 理 一 个 消 息 的 类 方 法ClassMethod 必 须 在 类 定 义 中 声 明, 且 有 实 现 代 码。 其 原 型 为:

---- Afx_msg return_type ClassMethod(paras table)

---- 类CCmdUI 专 门( 且 仅 仅) 与ON_UPDATE_COMMAND_UI 消 息 映 像 宏 配 套 使 用, 用 于 管 理 菜 单( 还 有 工 具 栏 按 扭 等) 的 实 时 状 态, 如 是 否 变 灰, 是 否 加 选 中 标 记 等。

---- ON_UPDATE_COMMAND_UI 消 息 映 像 宏 原 型 为:

---- ON_UPDATE_COMMAND_UI(Menu_Item_ID, Menu_Proc)

---- ON_UPDATE_COMMAND_UI 消 息 映 像 宏 将 一 个 菜 单 项( 命 令 项) 和 一 个 更 新 处 理 过 程 联 结, 从 而 在 适 当 的 时 机 自 动 调 用 此 更 新 处 理 过 程 来 完 成 对 菜 单 项 状 态 的 更 新。

---- Menu_Item_ID 为 菜 单 项 的ID 号,Menu_Proc 为 此 菜 单 项 的 更 新 处 理 函 数, 原 型 为:

---- afx_msg void Menu_Proc (CCmdUI* pCmdUI)

---- 它 带 有 一 个CCmdUI 类 指 针, 使 用 它 可 调 用CCmdUI 的 类 方 法。 与 菜 单 有 关 的 类 方 法 有:

Enable(BOOL) 使菜单项有效或无效

SetText(LPCTSTR) 设置菜单项的文本

SetCheck(int) 加上或去掉选中标记“X”

SetRadio(BOOL) 加上或去掉选中标记“.”

---- MenuProc 被 调 用 的 时 机 有 以 下 几 种 情 况:

---- 用 鼠 标 选 中 包 含 该 菜 单 项 的 菜 单 条

---- 用 热 键 选 中 包 含 该 菜 单 项 的 菜 单 条

---- 用 快 捷 键 选 中 与 该 菜 单 项 在 同 一 菜 单 条 下 的 任 一 菜 单 项

---- 我 们 以 下 面 菜 单 结 构 为 例:

Test menu

Item One ID_ITEM_ONE Ctrl+1

Item Two ID_ITEM_TWO Ctrl+2

Popup Popup One ID_POPUP_ONE Ctrl+3

Popup Two ID_POPUP_TWO Ctrl+4

---- 当 用 鼠 标 左 键 点 按Test menu 菜 单 条 或 按Alt+t 或 按Ctrl+1/2/3/4 时, 四 个 菜 单 项 的 更 新 处 理 过 程MenuProc 都 将 被 调 用。

---- 当 我 们 考 察 上 面 这 个 具 有 嵌 套 结 构 的 菜 单 时, 我 们 面 临 这 样 一 个 问 题: 菜 单 项Item One/Item Two 的 更 新 函 数 和Popup One/Popup Two 的 更 新 函 数 形 式 上 是 否 一 致 ? 当Popup One 和Popup Two 都 变 灰 时Popup 是 否 自 动 变 灰 ?

---- 根 据MFC 的 内 部 机 制, 仅 仅 弹 出 菜 单 的 第 一 项 应 附 加 一 些 代 码, 其 余 项 的 形 式 基 本 是 一 致 的。 也 就 是 说 在 上 例 中, 除 菜 单 项Popup One 外, 其 他 菜 单 项 更 新 函 数 的 代 码 基 本 一 致, 即 根 据 条 件, 简 单 调 用CCmdUI 类 方 法 即 可。 菜 单 项Popup One 由 于 是 弹 出 式 菜 单Popup 的 第 一 项, 它 的 更 新 函 数 在 以 下 两 种 情 况 下 都 会 被 调 用:

---- 当 弹 出 式 菜 单(Popup) 的 菜 单 项(Popup One 和Popup Two) 要 被 绘 出 时

---- 当 此 弹 出 式 菜 单 即Popup 本 身 要 被 绘 出 时

---- 第 一 种 情 况 很 好 理 解, 正 如 我 们 选 中Test menu 而Item One 和Item Two 的 更 新 函 数 会 自 动 执 行 一 样。 第 二 种 情 况 其 实 也 很 自 然, 因 为Popup 和Item One/Item Two 不 一 样, 它 没 有ID 号, 不 能 添 加 消 息 映 像 项, 那 么 它 的 状 态 如 何 更 新 呢 ? 于 是 它 的 第 一 项 的 更 新 函 数 被 调 用, 为 了 区 分 是 不 同 的 调 用, 它 将CCmdUI 的 类 成 员 变 量m_pSubMenu 设 置 为 不 同 的 值。 在 第 一 种 情 况 下,m_pSubMenu 等 于NULL, 第 二 种 情 况 下,m_pSubMenu 不 等 于NULL。

---- 以 下 我 们 给 出 一 个 实 际 的 编 程 范 例。 由 于 篇 幅 关 系, 我 们 仅 仅 给 出 一 些 关 键 的 语 句, 其 余 的 则 一 并 略 去。

---- 在 头 文 件 的 类 声 明 中:

BOOL m_bItemOne, m_bItemTwo, m_bPopupOne, m_bPopupTwo;

//用于决定各个菜单项的状态

protected:

afx_msg void OnUpdateMenuitemOne(CCmdUI* pCmdUI);

afx_msg void OnUpdateMenuitemTwo(CCmdUI* pCmdUI);

afx_msg void OnUpdatePopupOne(CCmdUI* pCmdUI);

afx_msg void OnUpdatePopupTwo(CCmdUI* pCmdUI);

//各菜单项的更新函数

DECLARE_MESSAGE_MAP()

在源文件中:

BEGIN_MESSAGE_MAP(CMyDoc, CDocument)

ON_UPDATE_COMMAND_UI (ID_ITEM_ONE,

OnUpdateMenuitemOne)

ON_UPDATE_COMMAND_UI (ID_ITEM_TWO,

OnUpdateMenuitemTwo)

ON_UPDATE_COMMAND_UI (ID_POPUP_ONE,

OnUpdatePopupOne)

ON_UPDATE_COMMAND_UI (ID_ POPUP_TWO,

OnUpdatePopupTwo)

END_MESSAGE_MAP()

void CMyApp::OnUpdatetMenuitemOne (CCmdUI* pCmdUI)

{

pCmdUI->Enable(m_bItemOne);

if(m_bItemOne) pCmdUI->SetText("Item One");

else pCmdUI->SetText("Item One is now disabled");

}

void CMyApp::OnUpdatetMenuitemTwo (CCmdUI* pCmdUI)

{

pCmdUI->Enable(m_bItemTwo);

if(m_bItemTwo) pCmdUI->SetText("Item Two");

else pCmdUI->SetText("Item Two is now disabled");

}

void CMyApp::OnUpdatePopupOne(CCmdUI* pCmdUI)

{

if (pCmdUI->m_pSubMenu != NULL)

{

BOOL b_Popup = m_bPopupOne || m_bPopupTwo;

pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex,

MF_BYPOSITION |

(bEnable ? MF_ENABLED :

(MF_DISABLED | MF_GRAYED)));

return;

}

pCmdUI->Enable(m_bPopupOne);

}

void CMyApp::OnUpdatePopupTwo(CCmdUI* pCmdUI)

{

pCmdUI->Enable(m_bPopupTwo);

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有