当前位置:首页 > 工业控制 > 电子设计自动化
[导读]当我们提到动态菜单的实现时,我们通常的做法是使用GetMenu() 函数获取一个Cmenu 类指针,然后调用CMenu 类方法AppendMenu, InsertMenu, ModifyMenu, RemoveMenu 等。本文介绍一种更加简洁的方法,它利用MFC 的消息映

当我们提到动态菜单的实现时,我们通常的做法是使用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);

}



来源:langen0次

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

声明:本处所说的菜单是用在128*64这种小屏幕的菜单,例如下面这种,不是彩屏上的GUI。

关键字: MCU GUI 菜单

14日,中兴通讯副总裁王全在中国国际信息通信展览会会上表示,“5G消息已经进入了商用的关键窗口期,万事俱备,只欠东风,需要产业链合作伙伴通力协作,建立共生共赢的产业生态,共同推动终端的快速普及和应用的升级迁移,加速5G消...

关键字: 5G 消息

郭明錤:业内最知名的分析师之一,看到他的名字大家都会想到关于苹果的最新消息。网友戏称其为“苹果爆料一哥”,确实每年在新iPhone机型发布之前他所分析的信息准确性达到70%以上,有这个能力的在智能手机

关键字: 库克 爆料 良心 苹果 消息

7 月 2 日消息 根据中国证券报 · 中证网的消息,中移互联网公司副总经理庄仁峰在 RCS-5G 消息论坛上介绍,当前,三家运营商都已经启动了 5G 消息商业化平台的建设工作。据介绍,RCS-5G

关键字: 5G 消息 运营商

6月24日,奥林巴斯中国在官网发布公告,表示将在2020年底完成以数码相机和IC录音笔为代表的映像业务转让,接手方是日本产业合作伙伴股份公司(JIP)。 奥巴称,此次转让协议对维持品牌资产、技术和产品

关键字: 业务 奥林巴斯 映像 相机

近日,一张疑似佳能EOS R5视频模式菜单的画面曝光网络,其中显示若干8K视频拍摄选项,以及不同的压缩模式,并且途中显示可录制的视频时间为21分31秒。泄露图展示了可以用8K DCI或者8K Ultra分辨率模式进行录制...

关键字: 佳能 菜单

前段时间,我国的三大网络运营商中国电信、中国移动和中国联通正式联合发布了《5G消息白皮书》。5G消息作为一款主推的5G产品得到了万千网友的热烈关注。

关键字: 5G 消息

当前,随着5G技术的快速发展,我国各大企业十分重视5G相关领域的发展。今年4月8日,我国三大网络运营商中国移动、中国电信和中国联通共同发布了《5G消息白皮书》,号召开启5G消息业务。

关键字: 5G 智能化 消息

菜单选项在Android手机中非常重要(例如,Android主屏幕,外部Android按钮和“通知”面板)。 某些手机(例如Samsung Galaxy Nexus)在主屏幕上没有菜单,而只有三个触摸按钮,即“主页”、“...

关键字: Android 菜单

在今日凌晨的在骁龙年度技术峰会上,伴随着骁龙865正式发布,小米集团联合创始人、副董事长林斌随即宣布将于明年第一季度发布小米10,作为小米十周年之际的旗舰作品,将首发骁龙865。 消息公布后,有米粉在

关键字: 官方 小米10 消息 米6 钉子户
关闭
关闭