MFC Ribbon菜单 - 中英文实时切换方法

简介

最近在搞一个老外的项目,本来谈的好好的,纯英文界面。项目接近尾声了,又提出了中英文实时切换的新需求,没办法就只能想办法,毕竟客户最大嘛。

实现方法

还好本来的ribbon英文菜单不复杂,就用纯C++编码的方式实现了中英文切换。方法如下:
1)添加一个ribbon分类,取名为"Language"
2) 在"Language"分类里添加一个Panel, 在Panel里添加一个Button, Button的名称为"Chinese"。
3) 为"Chinese"按钮添加消息响应函数。
4) 接下来就是在响应函数里编写切换的内容了。

Ribbon资源图

Chinese按钮属性

添加消息响应函数

编程实现中英文切换

cpp 复制代码
void CMainFrame::OnLanguage()
{
	//新添加的"Languae"在第5个分类栏,所以GetCategory(5)
	//Panel就一个,所以GetPanel(0)
	//按钮就一个,所以GetElement(0)
	//获取按钮上的文本,判断是"Chinese"还是"中文"
	CString str = m_wndRibbonBar.GetCategory(5)->GetPanel(0)->GetElement(0)->GetText();
	if (str == "Chinese") {
		if (IsValidCodePage(2052)) {
			MessageBox("The language Chinese Simplified PRC is not supported in this system.");
			return;
		}
		theApp.m_Lang = 2052;

		m_wndRibbonBar.GetCategory(0)->SetName("中文分类0");
		m_wndRibbonBar.GetCategory(0)->GetPanel(0)->GetElement(0)->SetText("按钮001");

		m_wndRibbonBar.GetCategory(1)->SetName("中文分类1");
		m_wndRibbonBar.GetCategory(1)->GetPanel(0)->GetElement(0)->SetText("按钮111");
		m_wndRibbonBar.GetCategory(1)->GetPanel(0)->GetElement(2)->SetText("按钮112");
		m_wndRibbonBar.GetCategory(1)->GetPanel(0)->GetElement(4)->SetText("按钮113");

		m_wndRibbonBar.GetCategory(1)->GetPanel(1)->GetElement(0)->SetText("按钮121");

		m_wndRibbonBar.GetCategory(1)->GetPanel(2)->GetElement(0)->SetText("检查框131");
		m_wndRibbonBar.GetCategory(1)->GetPanel(2)->GetElement(2)->SetText("检查框132");

		m_wndRibbonBar.GetCategory(2)->SetName("中文分类2");
		m_wndRibbonBar.GetCategory(2)->GetPanel(0)->GetElement(0)->SetText("按钮211");
		m_wndRibbonBar.GetCategory(2)->GetPanel(0)->GetElement(2)->SetText("按钮212");
		m_wndRibbonBar.GetCategory(2)->GetPanel(0)->GetElement(4)->SetText("按钮213");

		m_wndRibbonBar.GetCategory(3)->SetName("中文分类3");
		m_wndRibbonBar.GetCategory(3)->GetPanel(0)->GetElement(0)->SetText("按钮311");
		m_wndRibbonBar.GetCategory(3)->GetPanel(0)->GetElement(2)->SetText("按钮312");

		m_wndRibbonBar.GetCategory(4)->SetName("中文分类4");
		m_wndRibbonBar.GetCategory(4)->GetPanel(0)->GetElement(0)->SetText("按钮411");
		
		m_wndRibbonBar.GetCategory(5)->SetName("语言");
		m_wndRibbonBar.GetCategory(5)->GetPanel(0)->GetElement(0)->SetText("英文");
	}
	else {
		if (IsValidCodePage(1033)) {
			MessageBox("英文启动不支持,系统不能识别英文.");
			return;
		}
		theApp.m_Lang = 1033;
		
		m_wndRibbonBar.GetCategory(0)->SetName("Category0");
		m_wndRibbonBar.GetCategory(0)->GetPanel(0)->GetElement(0)->SetText("Button001");

		m_wndRibbonBar.GetCategory(1)->SetName("Category1");
		m_wndRibbonBar.GetCategory(1)->GetPanel(0)->GetElement(0)->SetText("Button111");
		m_wndRibbonBar.GetCategory(1)->GetPanel(0)->GetElement(2)->SetText("Button112");
		m_wndRibbonBar.GetCategory(1)->GetPanel(0)->GetElement(4)->SetText("Button113");

		m_wndRibbonBar.GetCategory(1)->GetPanel(1)->GetElement(0)->SetText("Button121");
		
		m_wndRibbonBar.GetCategory(1)->GetPanel(2)->GetElement(0)->SetText("Checkbox131");
		m_wndRibbonBar.GetCategory(1)->GetPanel(2)->GetElement(2)->SetText("Checkbox132");

		m_wndRibbonBar.GetCategory(2)->SetName("Category2");
		m_wndRibbonBar.GetCategory(2)->GetPanel(0)->GetElement(0)->SetText("Button211");
		m_wndRibbonBar.GetCategory(2)->GetPanel(0)->GetElement(2)->SetText("Button212");
		m_wndRibbonBar.GetCategory(2)->GetPanel(0)->GetElement(4)->SetText("Button213");

		m_wndRibbonBar.GetCategory(3)->SetName("Category3");
		m_wndRibbonBar.GetCategory(3)->GetPanel(0)->GetElement(0)->SetText("Button311");
		m_wndRibbonBar.GetCategory(3)->GetPanel(0)->GetElement(2)->SetText("Button312");

		m_wndRibbonBar.GetCategory(4)->SetName("Category4");
		m_wndRibbonBar.GetCategory(4)->GetPanel(0)->GetElement(0)->SetText("Button411");

		m_wndRibbonBar.GetCategory(5)->SetName("Language");
		m_wndRibbonBar.GetCategory(5)->GetPanel(0)->GetElement(0)->SetText("Chinese");
	}
	
	//这两行一定要加,否则ribbon不会重新计算位置和重画。
	m_wndRibbonBar.ForceRecalcLayout();
	m_wndRibbonBar.RedrawWindow();
}

注意事项

复制代码
在上面的代码中,可以看到有写panel里面获取element时,并不是0,1,2那样紧挨着获取的Element,而是0,2,4这样获取的Element。
那是因为Panel里面除了按钮之外,还有Seperator,就是分割线,他们是一种没有文本的分割线。所以要跳过分割线。

小结

复制代码
这种通过硬编码的方式修改Ribbon界面的方式比较笨,但是好在确实十分有效。目前我的项目已经在客户那里验证通过了,也算没白费。
相关推荐
智者知已应修善业12 分钟前
【删除有序数组中的重复项 II之O(N)算法】2024-1-31
c语言·c++·经验分享·笔记·算法
爱装代码的小瓶子14 分钟前
【c++进阶】C++11新特性:一切皆可{}初始化
开发语言·c++·visual studio
xiaoye-duck21 分钟前
吃透C++类和对象(中):构造函数与析构函数深度解析
c++
AA陈超21 分钟前
Lyra Starter Game 中 GameFeature 类(如 ShooterCore)的加载流程
c++·笔记·学习·ue5·虚幻引擎
加成BUFF40 分钟前
C++入门讲解3:数组与指针全面详解
开发语言·c++·算法·指针·数组
天若有情6731 小时前
我发明的PROTO_V4协议:一个让数据“穿上迷彩服”的发明(整数传输协议)
网络·c++·后端·安全·密码学·密码·数据
加油=^_^=1 小时前
【C++11】特殊类设计 | 类型转换
c++·单例模式·类型转换
加成BUFF1 小时前
C++入门详解2:数据类型、运算符与表达式
c语言·c++·计算机
徐行code1 小时前
std::bind()和lambda的区别
c++
小老鼠不吃猫2 小时前
C++20 STL <numbers> 数学常量库
开发语言·c++·c++20