MFC 应用程序语言切换

在开发多语言支持的 MFC 应用程序时,如何实现动态语言切换是一个常见的问题。在本文中,我们将介绍两种实现语言切换的方式,并讨论其优缺点。同时,我们还会介绍如何通过保存配置文件来记住用户的语言选择,以及如何在程序启动时加载该语言设置。


第一种方式:通过资源切换实现语言切换

基本思路

在这种方式中,通过将应用程序的主要资源文件扩展为多语言版本(如中文和英文),并在程序运行时根据需要加载对应的资源来实现语言切换。

实现步骤

  1. 资源文件的多语言版本创建

    • 为每种语言创建独立的资源文件版本(如简体中文和英文)。
    • 在资源视图中添加各自的语言对话框和字符串表。
  2. 加载对应语言的资源

    • 使用 SetThreadUILanguageSetThreadLocale 动态设置线程的语言和区域设置。
    • 在应用程序启动时,根据语言配置文件选择合适的资源。
  3. 保存语言配置文件

    • 使用 .ini 文件保存用户选择的语言。
    • 例如:
      [Settings]
      Language=zh-CN
      

优点

  • 易于实现,直接利用 MFC 的多语言资源支持。
  • 无需动态加载外部 DLL。

缺点

  • 程序体积较大,因为所有语言的资源都嵌入在一个 EXE 文件中。
  • 无法动态扩展语言,需要重新编译程序。

第二种方式:通过资源动态库实现语言切换

基本思路

在这种方式中,将每种语言的资源文件提取到独立的 DLL 文件中,程序运行时根据用户选择动态加载对应的资源 DLL。这样可以实现程序的轻量化,并支持动态扩展语言包。

实现步骤

  1. 创建语言资源动态库

    • 创建多个独立的资源 DLL 项目,例如 MFCApplication_en.dllMFCApplication_zh.dll
    • 每个 DLL 包含对应语言的资源。
  2. 动态加载资源库

    • 在程序运行时,使用 AfxLoadLibrary 动态加载指定的资源 DLL。
    • 使用 AfxSetResourceHandle 设置当前使用的资源句柄。
  3. 保存语言配置文件

    • 与第一种方式类似,使用 .ini 文件保存用户选择的语言。

优点

  • 程序体积较小,每种语言的资源独立存储。
  • 支持动态扩展语言,只需添加新的 DLL 即可。

缺点

  • 实现复杂度较高,需要处理 DLL 的加载与释放。
  • 程序运行时依赖外部资源文件(DLL)。

保存语言设置并实现自动加载

无论使用哪种方式,都需要保存用户的语言选择,并在程序启动时自动加载对应的语言设置。

初始化和退出实例

程序启动时自动加载;程序退出时释放资源库:

// CMFCApplicationApp 初始化BOOL CMFCApplicationApp::InitInstance()
{// 省略......// 加载语言配置CString language = LoadLanguageFromIni();SetLanguage(language);// 省略......return FALSE;
}int CMFCApplicationApp::ExitInstance()
{if (g_hCurrentResource != NULL) {FreeLibrary(g_hCurrentResource);	// 释放当前资源库g_hCurrentResource = NULL;			// 清空资源句柄}return CWinApp::ExitInstance();
}

保存语言到 .ini 文件

以下代码用于保存用户选择的语言到 .ini 文件:

void CMFCApplicationApp::SaveLanguageToIni(const CString& language)
{// 获取当前执行文件的目录TCHAR szPath[MAX_PATH];GetModuleFileName(NULL, szPath, MAX_PATH);CString strPath = szPath;strPath = strPath.Left(strPath.ReverseFind('\\')) + _T("\\Settings.ini");// 保存语言配置到 .ini 文件WritePrivateProfileString(_T("Settings"), _T("Language"), language, strPath);
}

加载语言设置

在应用程序启动时,读取 .ini 文件,加载对应的语言设置:

CString CMFCApplicationApp::LoadLanguageFromIni()
{TCHAR szPath[MAX_PATH];GetModuleFileName(NULL, szPath, MAX_PATH);CString strPath = szPath;strPath = strPath.Left(strPath.ReverseFind('\\')) + _T("\\Settings.ini");TCHAR szLanguage[16] = { 0 };GetPrivateProfileString(_T("Settings"), _T("Language"), _T("en-US"), szLanguage, 16, strPath);return CString(szLanguage);
}

设置语言

在应用程序启动时,设置语言的两种方式:

void CMFCApplicationApp::SetLanguage(const CString& language)
{
#if 1LANGID idLang = 0;if (language == _T("zh-CN")) {idLang = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);}else if (language == _T("en-US")) {idLang = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);}if (idLang != 0) {SetThreadUILanguage(idLang);SetThreadLocale(idLang);}
#elseCString strLanguage;if (language == _T("zh-CN")) {strLanguage.Format(_T("MFCApplication_zh.dll"));}else if (language == _T("en-US")) {strLanguage.Format(_T("MFCApplication_en.dll"));}// 加载新的资源库g_hCurrentResource = AfxLoadLibrary(strLanguage);// 设置新的资源句柄if (g_hCurrentResource != NULL) {AfxSetResourceHandle(g_hCurrentResource);}
#endif // 0
}

实现语言切换后自动重启

为了应用新的语言设置,可以在用户切换语言后重启应用程序:

重启实现代码

在主对话框中,当用户点击按钮切换语言后,保存设置并触发程序重启:

void CMFCApplicationDlg::OnBnClickedButtonTestCN()
{theApp.SaveLanguageToIni(_T("zh-CN"));m_bRestartFlag = TRUE;PostMessage(WM_CLOSE, 0, 0);
}void CMFCApplicationDlg::OnBnClickedButtonTestUS()
{theApp.SaveLanguageToIni(_T("en-US"));m_bRestartFlag = TRUE;PostMessage(WM_CLOSE, 0, 0);
}void CMFCApplicationDlg::OnClose()
{if (m_bRestartFlag) {CString strFileName = _T("");GetModuleFileName(NULL, strFileName.GetBuffer(MAX_PATH), MAX_PATH);ShellExecute(NULL, _T(""), strFileName, NULL, NULL, SW_SHOWNORMAL);strFileName.ReleaseBuffer();}CDialogEx::OnClose();
}

总结

通过上述两种方式,可以实现 MFC 应用程序的多语言支持:

  • 方式一适用于语言资源固定、无需动态扩展的情况。
  • 方式二适用于需要动态扩展语言资源的情况。
  • 文件化存储方式
    • 将所有控件的 ID 和文本保存到文件中(例如 .ini 或 .json 文件)。
    • 程序运行时动态加载文件内容,更新控件的文本。
    • 无需重启即可切换语言。

通过保存用户选择的语言设置,并在程序启动时加载对应的语言,用户可以获得无缝的多语言体验。同时,结合程序的重启机制,可以确保语言切换后的即时生效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/890217.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于海思soc的智能产品开发(巧用mcu芯片)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 对于开发车规级嵌入式软件的同学来说,socmcu这样的组合,他们并不陌生。但是传统的工业领域,比如发动机、医疗或…

带有 Elasticsearch 和 Langchain 的 Agentic RAG

作者:来自 Elastic Han Xiang Choong 讨论并实现 Elastic RAG 的代理流程,其中 LLM 选择调用 Elastic KB。 更多阅读:Elasticsearch:基于 Langchain 的 Elasticsearch Agent 对文档的搜索。 简介 代理是将 LLM 应用于实际用例的…

SmartX分享:NVMe-oF 介绍、SMTX ZBS 如何选择高性能场景解决方案与如何实现

目录 背景什么是 NVMe-oFZBS AccessiSCSI 与 iSERNMVe-oF 介绍NVMeNVMe-oFNVMe-oF 承载网络(数据平面) ZBS NVMe-oF 实现ZBS 接入策略ZBS 接入点分配策略性能测试 为什么要支持 RoCE引用 背景 前几篇文章,我们认识到了 SmartX 公司产品 SMTX…

【机器学习】机器学习的基本分类-强化学习(Reinforcement Learning, RL)

强化学习(Reinforcement Learning, RL)是一种基于试错的方法,旨在通过智能体与环境的交互,学习能够最大化累积奖励的策略。以下是强化学习的详细介绍。 强化学习的核心概念 智能体(Agent) 执行动作并与环境…

MyBatis-Plus中isNull与SQL语法详解:处理空值的正确姿势

目录 前言1. 探讨2. 基本知识3. 总结 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 基本的Java知识推荐阅读: java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全&#x…

Spring Boot 项目创建

创建一个新项目: 打开 Spring Initializr 网址:https://start.spring.io/ ,然后创建一个新项目: springboot3.3.5_jdk17: Project(Maven)编程语言(Java 17)Spring Boo…

基于蓝牙通信的手机遥控智能灯(论文+源码)

1.系统设计 灯具作为人们日常生活的照明工具为人们生活提供光亮,本次基于蓝牙通信的手机遥控智能灯设计功能如下: (1)用户可以通过蓝牙通信模块的作用下,在手机端遥控切换智能灯不同的工作模式; &#x…

为什么光耦固态继电器(SSR)值得关注?

光耦固态继电器(SSR)作为现代电子控制系统中不可或缺的关键组件,正逐步取代传统机械继电器。通过利用光耦合技术,SSR不仅能够提供更高的可靠性,还能适应更加复杂和严苛的应用环境。在本文中,我们将深入探讨…

AI @国际象棋世界冠军赛: 从棋盘到科研创新之路

点击屏末 | 阅读原文 | 在小红书和 Google 谷歌回顾 WCC

leetcode二叉搜索树部分笔记

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 二叉搜索树 1. 二叉搜索树的最小绝对差2. 二叉搜索树中第 K 小的元素3. 验证二叉搜索树 1. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root ,返回 树中…

计算机工作流程

分析下面的计算机工作流程: 1.取数a至ACC:PC程序寄存器自增1,变成0(可以理解为PC初始从-1开始自增);接着PC把当前指令的地址给到MAR(地址寄存器);MAR拿到当前地址后&…

ffmpeg翻页转场动效的安装及使用

文章目录 前言一、背景二、选型分析2.1 ffmpeg自带的xfade滤镜2.2 ffmpeg使用GL Transition库2.3 xfade-easing项目 三、安装3.1、安装依赖([参考](https://trac.ffmpeg.org/wiki/CompilationGuide/macOS#InstallingdependencieswithHomebrew))3.2、获取…

Elasticsearch8.17.0在mac上的安装

1、下载并安装 下载8.17版本es(目前最新版本):Download Elasticsearch | Elastic 也可以通过历史版本列表页下载:Past Releases of Elastic Stack Software | Elastic 当然也可以指定具体版本号进行下载:Elasticsearch 8.17.0 | Elastic …

解决Apache/2.4.39 (Win64) PHP/7.2.18 Server at localhost Port 80问题

配置一下apache里面的配置文件:httpd.conf 和 httpd.vhosts.conf httpd.conf httpd-vhosts.conf 重启服务 展示: 浏览器中中文乱码问题:

git 删除鉴权缓存及账号信息

在Windows系统下 清除凭证管理器中的Git凭据 按下Win R键,打开“运行”对话框,输入control,然后回车,打开控制面板。在控制面板中找到“用户账户”,然后点击“凭据管理器”。在凭据管理器中,找到“Windows…

MacOS下PostIn安装配置指南

PostIn是一款开源免费的接口管理工具, 下面介绍私有部署版本的MacOS下安装与配置。私有部署版本更适合有严格数据安全要求的企业,实现对数据和系统的完全控制。   1、MacOS服务端安装 Mac安装包下载地址:下载Mac安…

最适合智能体的身份认证技术:对比OpenID Connect、API keys、did:wba

最适合智能体的身份认证技术:对比OpenID Connect、API keys、did:wba 智能体需要新的身份认证技术 智能体对身份认证技术提出了新的需求,其中最重要的一个就是互联互通,特别是让任意两个智能体都能够互联互通。 其中的原理很简单:…

排序算法(7):堆排序

问题 排序 [30, 24, 5, 58, 18, 36, 12, 42, 39] 堆排序 堆排序是一种基于堆数据结构的排序算法。堆是一个近似完全二叉树的结构,即除了最后一层外,每一层都必须填满,且最后一层从左往右填充。 堆可以分为大根堆和小根堆。在大根堆中&…

多核CPU调度是咋搞的?

其实很多情况下都有 这样的疑问 为什么多核CPU用着用着会“躺平”? 为什么手机有 8 核,跑分时性能却不是核心数的翻倍? 答案的钥匙,就藏在多核CPU的调度机制里。 为了更直观地理解,以一个《王者荣耀》游戏服务器为例…

Qt Quick:CheckBox 复选框

复选框不止选中和未选中2种状态哦,它还有1种部分选中的状态。这3种状态都是Qt自带的,如果想让复选框有部分选中这个状态,需要将三态属性(tristate)设为true。 未选中的状态值为0,部分选中是1,选…