CMFCMenuBar和CMFCToolBar相同ID,在显示不同标签文字

原创 2012年06月15日 18:23:31

由于要使用多国语言动态切换, 而CMFCMenuBar 和 CMFCToolBar又比较难用.

1. CMFCMenuBar菜单栏中的菜单项文字修改可没有普通的菜单那么简单,它其实是由CMFCToolBar派生而来.所以能直接调用此类的对象修改的文字,就只有第一级菜单了.如果放到单文档中,即是像单文档主菜单的  "文件","编辑"这一层一直显示在窗口上的菜单项. 而这一级菜单是没有ID的,其属性是POP_UP. 就只能使用按如下方法修改其文字.

//更新菜单栏父项,即无ID的项.
	CAdoString Str;
	CMFCToolBarButton  *pButton = NULL;
	int Index = 0;
	do
	{
		pButton = m_wndMenuBar.GetMenuItem(Index);
		if(pButton)
		{
			//由于无ID,就只能按索引来修改了,这里只修改了索引为0的菜单项,在单文档中是"文件"菜单项
			if(Index == 0)
			{
				Str.LoadString(TEXT("IDS_FILE"));
				pButton->m_strText = Str;
			}

		}
		++Index;
	}
	while( pButton != NULL );


2. 对于其一级菜单弹出的子菜单,简单的办法就是使用 ON_UPDATE_COMMND_UI来更新.

    不过,这个时候就有一个问题, 当你响应了这个消息,修改了菜单的文字,你会发现如果工具栏中ID相同的项的文字也跟着改变了.

   在一般情况下,工具栏上显示的文字都不会想和菜单对应ID项的文字一样.  比如有一个菜单项,叫"保存到U盘"而工具栏有个U盘图标,一般只需要写一个"保存"就好了.

   工具栏的文字单独加载:代码如下:

UINT itemID = 0;
	int nCount  = m_wndToolBar.GetCount();
	for( int i=0 ;i<nCount; ++i)
	{
		if( TBBS_SEPARATOR != m_wndToolBar.GetButtonStyle(i) )
		{
			itemID = m_wndToolBar.GetItemID(i);
			switch(itemID)
			{
			case ID_FILE_NEW:
				Str.LoadString(TEXT("TOOL_NEW"));
				m_wndToolBar.SetToolBarBtnText(i,Str);
				break;
			case ID_FILE_OPEN:
				Str.LoadString(TEXT("TOOL_OPEN"));
				m_wndToolBar.SetToolBarBtnText(i,Str);
				break;
			case ID_FILE_SAVE:
				Str.LoadString(TEXT("TOOL_SAVE"));
				m_wndToolBar.SetToolBarBtnText(i,Str);
				break;
			case ID_FILE_PRINT:
				Str.LoadString(TEXT("TOOL_PRINT"));
				m_wndToolBar.SetToolBarBtnText(i,Str);
				break;
			}
		}
		
	}


  

3.  开始为了解决这个问题,我重载了CMFCToolBar类的OnUpdateCmdUI函数,直接返回,什么不做,  这样工具栏文字不跟着更新了. 

但是又有一个问题出现, 那就是工具栏状态也不跟着菜单的状态改变了, 菜单项变成禁用时,此工具栏仍然显示可用.


4.  我跟踪到CMFCToolBar::OnUpdateCmdUI这个函数中,发现在这个类中定义了一个私有的类 CToolCmdUI类,这个类继承自CCmdUI. 并且在函数SetText会被调用.

所以我又想到既然重载了这个函数,那么把这个私有的类,复制过来,重写过,把SetText直接给返回,什么也不做.

当然,这样做,动态更新文字时,或者响应ON_UPDATE_COMMND_UI时,工具栏的文字已经不会变化了,看似达到了要求.

但是当我点击一下工具栏上的按钮时,发现工具栏上的文字竟然又变成和菜单项的文字一样了. ....


5. 后来为了看菜单项的ON_UPDATE_COMMND_UI消息和工具栏的SetText有什么不同, 下了个断点,发现会一个断下来,因为这个消息会在空闲时调用.为了只在菜单栏被更新时调用 ,就想区分掉菜单和工具栏的更新. 最终发现CCmdUI::m_pMenu在工具栏更新时为NULL. 就这样可以只在菜单更新时断下来了.但是跟进去没发现有什么不同的.

准备放弃了.就随便发泄式的乱点......

但是开心的事来了,竟然工具栏符合我的要求,没有变成和菜单相同了,

难道就是刚才加的那句判断不同的地方, 突然一想,是啊,这么简单,怎么前面就没想到呢. 果断去掉 3,4中修改的代码. 再运行,仍然能按我想的工作.

确实就这么简单变OK了.

void CMainFrame::OnUpdateFileNew(CCmdUI *pCmdUI)
{
	CAdoString Str;
	Str.LoadString(TEXT("IDS_FILE_NEW"));
	if(pCmdUI->m_pMenu != NULL)
	{
		pCmdUI->SetText(Str);
	}
}

这下,工具栏文字也任我操作了.


但还有问题没有解决,是关于菜单的.

菜单中如果弹出的菜单中还有弹出菜单的话,这个二级的弹出菜单的项仍然是没有ID的,怎么修改它的标签文字呢,CMFCMenuBar类是没有办法了.

网上搜索了下, 一种比较复杂的方法是先获得CMFCMenuBar关联的菜单句柄, 然后就可以使用API来修改菜单了,修改完再设置回去. 暂时还没有试,有时间再试了.


动态修改CMFCMenuBar及CMFCToolBar的文字及Prompt,ToolTip文字

1. 修改CMFCMenuBar菜单项的文字,分两种.   A. 修改顶层有POP_UP属性的菜单文字,即类型单文档中的" 文件" ,"编辑","视图"等这类一直显示着的.     因为C...

动态修改CMFCMenuBar及CMFCToolBar的文字及Prompt,ToolTip文字.

动态修改CMFCMenuBar及CMFCToolBar的文字及Prompt,ToolTip文字. 1. 修改CMFCMenuBar菜单项的文字,分两种.   A. 修改顶层有POP_UP属性的...

pol选择相同ID面

  • 2015年04月02日 11:25
  • 954B
  • 下载

获得所有相同控件的id

  • 2011年04月19日 09:52
  • 20KB
  • 下载

VS2008中的多个CMFCToolBar,在同一行显示!

我创建的mfc多文本工程中有5个工具栏。开始创建出来是效果是这样的。 式样很丑!所以我想把做成类似Office的工具栏那样。经过几天的百度。。谷歌终于找到想要的函数DockPaneLeftOf();...

Android UI设计之<六>使用HTML标签,实现在TextView中对部分文字进行加粗显示

搞软件开发的都知道项目中各种需求都有,而有时候各种奇葩的需求真是让人大跌眼镜,为了实现这些奇葩的需求我们往往苦逼的废寝忘食,我现在的项目中就有一个应该算得上奇葩的需求吧,需求是这样的:在一段文字中实现...

HTML常用文字显示标签效果示例

初学HTML 一眼望去 全是标签,瞬间头大了!做个效果图片方便记忆,以供大脑内存不足时重新查找资料之用! 以下是 html代码,小白练手Demo,没什么技术含量: 常用...

《学习opencv》课后题:4.1.c如何显示文字标签?

如何使用opencv添加文本。

winform tabcontrol控件的标签放到左边后,文字成是上下显示的

winform tabcontrol控件的标签放到左边后,文字成是上下显示的 using   System;  using   System.Drawing;  usin...

获取UILabel每一行显示的文字(UILabel 最后一行显示标签)

今天遇到一个需求,要在label的后面加上一个button 作为tag,如图思路(比较笨的办法): 使用两个UILabel,每一行就是一个只显示一行的Label,第一个label的截断设置为NSLi...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:CMFCMenuBar和CMFCToolBar相同ID,在显示不同标签文字
举报原因:
原因补充:

(最多只允许输入30个字)