当前位置: 首页 > news >正文

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 文件)。
    • 程序运行时动态加载文件内容,更新控件的文本。
    • 无需重启即可切换语言。

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

相关文章:

MFC 应用程序语言切换

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

与您的数据对话: 用人工智能驱动的对象存储变革医疗保健

MinIO 的提示 API 现在是 AIStor 的一部分。MinIO 的创建是为了支持海量数据集,包括超过 EB 级的工作负载,解决内存、网络、复制和负载均衡方面的挑战,而 AIStor 的创建是为了建立在这些功能之上并解决我们客户的 AI 使用案例。作为 AIStor 的…...

WIN10拖入文件到桌面,文件自动移动到左上角,导致桌面文件错乱

1.先打开文件管理器。 2.点击如下图所示的“选项”。 3.我用红笔标记的这个框,把勾去掉...

JavaSE——绘图入门

一、Java绘图坐标体系 下图说明了Java坐标系,坐标原地位于左上角,以像素为单位。在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直…...

electron-vite打包后图标不生效问题

在electron-builder.yml中,通过icon配置自己的图标,以下是正确代码 win:executableName: 名称icon: build/icon.ico nsis:artifactName: ${name}-${version}.${ext}shortcutName: ${productName}uninstallDisplayName: ${productName}createDesktopShor…...

【MySQL】Linux使用C语言连接安装

📢博客主页:https://blog.csdn.net/2301_779549673 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 JohnKi 原创,首发于 CSDN🙉 📢未来很长&#…...

Linux计算时间差

Linux计算时间差 1、Linux计算时间差2、时间差的应用 1、Linux计算时间差 在Linux中,计算时间差通常是为了统计、监控或调试。时间差可以用来衡量任务执行的时间,或者两个事件之间的间隔。例如,响应时间、执行时间、定时任务与延时处理等 以…...

onlyoffice连接器 二次开发 合同等制式模板化技术开发方案【三】

一、期望效果 目前曹瑞版本onlyoffice已经实现:书签模式 和 控件模式,用以支持该方案。 【图1】字段绑定 【图2】模板发起 【图3】接入表单 思路讲解: 业务系统开发中通常希望能够通过绑定form字段给word,从而达到双向同步效果&am…...

【论文研读】U-DiTs:在U型扩散Transformer中引入下采样Token,以更低计算成本超越DiT-XL/2

推荐理由 这篇论文提出了一种新的U型扩散Transformer模型(U-DiT),该模型通过对自注意力机制中的查询、键和值进行下采样,有效减少了计算冗余,同时提高了性能。论文中的研究不仅包含理论分析和实验验证,还展…...

2009 ~ 2019 年 408【计算机网络】大题解析

2009 年 路由算法(9’) 讲解视频推荐:【BOK408真题讲解-2009年(催更就退网版)】 某网络拓扑如下图所示,路由器 R1 通过接口 E1 、E2 分别连接局域网 1 、局域网 2 ,通过接口 L0 连接路由器 R2 &…...

.net core在linux导出excel,System.Drawing.Common is not supported on this platform

使用框架 .NET7 导出组件 Aspose.Cells for .NET 5.3.1 asp.net core mvc 如果使用Aspose.Cells导出excel时,报错 : System.Drawing.Common is not supported on this platform 平台特定实现: 对于Windows平台,System.Drawing.C…...

ExcelVBA编程输出ColorIndex与对应颜色色谱

标题 ExcelVBA编程输出ColorIndex与对应颜色色谱 正文 解决问题编程输出ColorIndex与对应色谱共56,打算分4纵列输出,标题是ColorIndex,Color,Name 1. 解释VBA中的ColorIndex属性 在VBA(Visual Basic for Applications)中&#xff…...

3.使用SD卡挂载petalinux根文件系统

前言 说明为什么使用SD卡挂载petalinux根文件系统如何使用SD卡挂载根文件系统 配置根文件写入类型制作SD分区格式化SD卡将工程目录下的rootfs.tar.gz解压到SD EXT4分区 为什么使用SD卡挂载petalinux根文件系统 Petalinux 默认的根文件系统类型是 INITRAMFS,不能…...

Java反射学习(1)(Java的“反射“机制、Class类对象的实例化方式)

目录 一、Java的"反射"机制。 (1)生活中的"反射"例子。 (2)Java的"反射"机制。 1、Java程序中"反射"的基本介绍。 2、"反射"机制图解介绍。 3、"反射"常见的应用场景…...

paimon中的Tag

TAG 在传统数仓场景中,从传统数据库中导入的事实表数据一般是全量导入,按天分区每天都存储一份全量数据,paimon对此提供了Tag机制,创建TAG时,会对当前数据做一份全量快照,在之后对表的数据进行更新也不会影…...

使用Vue创建前后端分离项目的过程(前端部分)

前端使用Vue.js作为前端开发框架,使用Vue CLI3脚手架搭建项目,使用axios作为HTTP库与后端API交互,使用Vue-router实现前端路由的定义、跳转以及参数的传递等,使用vuex进行数据状态管理,后端使用Node.jsexpress&#xf…...

4、交换机IP接口功能

这一篇是讲端口的功能的,应该放在路由前面的,不过关联不大,就这个顺序也行 1、DHCP功能 作用:交换机端口的DHCP功能可以使网络中的设备(计算机、打印机等等)能够自动的获取IP地址或其它网络参数&#xff0…...

java 选择排序,涵盖工作原理、算法分析、实现细节、优缺点以及一些实际应用场景

选择排序的详细解析 更深入地探讨选择排序的各个方面,包括其工作原理、算法分析、实现细节、优缺点以及一些实际应用场景。 动画演示 1. 基本概念 选择排序是一种简单的比较排序算法。它的核心思想是将数组分为两个部分:已排序部分和未排序部分。每…...

基于springboot+vue实现的医院急诊(病房)管理系统 (源码+L文+ppt)4-122

摘要 医院急诊(病房)管理系统旨在优化患者的就诊流程,提高医疗效率和服务质量。该系统通过电子化患者信息、实时床位监控和智能调度等功能,确保急诊患者能够快速得到必要治疗,同时协助医护人员高效管理病房资源。系统…...

前端模块化

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1.概述1.1什么是模块化1.2为什么要使用模块化 2.有哪些模块化规范3.CommonJS3.1导入3.1.1正常导入3.1.2解构导入 3.2导出3.2.1exports导出3.2.2module.exports导…...

​在VMware虚拟机上设置Ubuntu与主机共享文件夹​

‌在VMware虚拟机上设置Ubuntu与主机共享文件夹的步骤如下‌: ‌主机共享文件夹的设置‌:首先,在主机上选择一个磁盘分区创建一个文件夹,并设置其共享属性。右键点击该文件夹,选择“属性”,然后在“共享”选…...

无线信道常识(符号与多径、窄带与宽带)

符号长度与时延扩展 符号长度: 符号长度是指一个符号(即一个信息单元)在传输过程中所占用的时间。符号长度通常与系统的带宽和调制方式有关。例如,在GSM系统中,符号长度大约为 5μs。 时延扩展: 时延扩展是…...

人工智能 (AI) 模型的数据泄露问题

目录 1. 数据泄露:2. 模型泄露:3. 社会工程学攻击:参考文献:其他资源: 人工智能 (AI) 模型的数据泄露问题指的是模型训练过程中,训练数据的信息被泄露到模型输出中,导致模型对未见过的数据产生偏差或错误预测。这种泄露可能来自多个方面,包括…...

uniapp Vue3 语法实现浏览器中音频录制、停止、保存、播放、转码、实时音频输出

一、引言 在现代 Web 应用开发中,音频处理功能变得越来越重要。本文将详细介绍如何使用 uniapp 结合 Vue3 语法在浏览器环境中实现音频录制、停止、保存、播放、转码以及实时音频输出等一系列功能。通过深入剖析代码结构和功能实现细节,帮助读者全面理解和掌握相关技术,以便…...

OSPF的基本配置

基本原理图 1. 要求: R1-3为区域0,R3-R4为区域1;其中r3的环回也在区域0。R1,R2也各有一个环回 R1-R3 R3为DR设备,没有BDR R4环回地址以固定,其他所有网段使用192.168.1.0/24进行合理的分配 R4环回不能宣告&#xff0…...

【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互

前言 欢迎来到第二篇文章,这也是第二个难题,就是原有的移动端本身一些页面H5的形式去呈现(webview),例如某些需要动态更换内容的页面,某些活动页面、支付页面,不仅仅做页面呈现,还包…...

【游戏中orika完成一个Entity的复制及其Entity异步落地的实现】 1.ctrl+shift+a是飞书下的截图 2.落地实现

一、orika工具使用 1)工具类 package com.xinyue.game.utils;import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.impl.DefaultMapperFactory;/*** author 王广帅* since 2022/2/8 22:37*/ public class XyBeanCopyUtil {private static MapperFactory mappe…...

全局JDK环境和ES自带的JDK混用导致的ES集群创建失败

es配置安全集群es使用的自带的jdk环境,如果服务器全局在有jdk的配置。会导致秘钥解析出问题。各种问题异常密钥解析异常。 错误日志1: [2024-12-20T17:10:44,700][WARN ][o.e.c.c.ClusterFormationFailureHelper] [es-node1] master not discovered yet…...

vmime.net_4.dll详解:它是什么,有何用途?

在.NET开发环境中,DLL(Dynamic Link Library,动态链接库)文件扮演着至关重要的角色。它们封装了代码和资源,使得多个应用程序可以共享这些功能,从而提高开发效率和代码复用性。本文将详细介绍vmime.net_4.d…...

K8s 节点 NotReady 后 Pod的变化

NotReady 后 Pod的变化 当Kubernetes(K8s)节点进入NotReady状态时,该节点将无法接收新的Pod调度,这可能会影响服务的可用性。以下是节点变为NotReady后,其上Pod状态可能发生的一些情况和细节: Pod状态变为…...

使用 esrally race 测试 Elasticsearch 性能:实践指南

在 Elasticsearch 性能优化和容量规划中,使用 esrally 进行基准测试是官方推荐的方式。通过 esrally race 命令,您可以针对不同的数据集与挑战类型,对 Elasticsearch 集群进行精确的性能评估。本文将简要介绍常用的数据集与挑战类型&#xff…...

对象、函数、原型之间的关系

在 JavaScript 中,对象、函数 和 原型 是三者紧密联系的核心概念。它们共同构成了 JavaScript 中面向对象编程的基石,并通过原型链实现了继承与代码复用。本文将从对象、函数、原型的基础概念到它们之间的关系进行详细的讲解,帮助你理解 Java…...

Showrunner AI技术浅析(二):大型语言模型

1. GPT-3模型架构详解 GPT-3是基于Transformer架构的预训练语言模型,由OpenAI开发。其核心思想是通过自注意力机制(Self-Attention)处理输入序列,并生成自然语言文本。 1.1 Transformer架构基础 Transformer架构由Vaswani等人在…...

Web安全攻防入门教程——hvv行动详解

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻防…...

买卖股票的最佳时机 - 合集

************* C 买卖股票问题合集 ************* Since I have finished some stocks problems. I wanna make a list of the stocks to figure out the similarities. Here is the storks topucs list, from easy to hard: 121. 买卖股票的最佳时机 - 力扣(L…...

gitlab window如何设置ssh

在GitLab中设置SSH需要以下步骤: 在GitLab账户中,导航到“用户设置”下的“SSH密钥”部分。 生成SSH密钥对(如果你还没有的话)。在Windows上,你可以使用ssh-keygen命令来生成密钥。 在命令提示符或PowerShell中运行以…...

go配置文件

https://github.com/spf13/viper viper golang中常用的配置文件工具为viper库,是一个第三方库。viper功能: 解析JSON、TOML、YAML、HCL等格式的配置文件。监听配置文件的变化(WatchConfig),不需要重启程序就可以读到最新的值。...

深度学习之超分辨率算法——SRGAN

更新版本 实现了生成对抗网络在超分辨率上的使用 更新了损失函数,增加先验函数 SRresnet实现 import torch import torchvision from torch import nnclass ConvBlock(nn.Module):def __init__(self, kernel_size3, stride1, n_inchannels64):super(ConvBlock…...

GIT命令使用手册(详细实用版)

一、git常用操作参考 第一次提交完整步骤: 1.git init; 2.git add . 3.git commit -m "初始化" 4.git remote add origin https://github.com/githubusername/demo.git 5.git pull origin master 6.git push -u origin master(使用-u选项可以将…...

数据分析实战—IMDB电影数据分析

1.实战内容 1.加载数据到movies_df,输出前5行,输出movies_df.info(),movies_df.describe() # (1)加载数据集,输出前5行 #导入库 import pandas as pd import numpy as np import matplotlib import matplotlib.pyplo…...

【SQL/MySQL 如何使用三种触发器】SQL语句实例演示

触发器介绍 – 触发器是与表有关的数据库对象,指在insert/update/delete之前(BEFORE)或之后(AFTER),触发并执行触发器中定义的SQL语句集合。 – 使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只…...

社区团购管理系统(源码+数据库)

355.基于SpringBoot的社区团购管理系统,系统包含两种角色:管理员、用户,系统分为前台和后台两大模块,主要功能如下 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue …...

时钟分频模块

实现时钟的二分频,四分频 1.时钟分频模块: module clk_div(input clk, //50Mhzinput rst_n,input [15:0] lcd_id,output reg lcd_pclk);reg clk_25m; reg clk_12_5m; reg …...

linux ipmitool配置机器的BMC(服务器管理后台)

前置:mgnt口和网卡1连接入内网,并分配静态ip 1. 安装 ipmitool Debian/Ubuntu: sudo apt-get update sudo apt-get install ipmitool CentOS/RHEL: sudo yum install ipmitool2. 配置 BMC 的 IP 地址 #打印当前ipmi 地址配置信息。 ipmitool lan p…...

【Springboot知识】Redis基础-springboot集成redis相关配置

文章目录 1. 添加依赖2. 配置Redis连接3. 配置RedisTemplate(可选)4. 使用RedisTemplate或StringRedisTemplate5. 测试和验证 集群配置在application.properties中配置在application.yml中配置 主从配置1. 配置Redis服务器使用配置文件使用命令行 2. 配置…...

【数据结构】八大排序

目录 一、直接插入排序 二、希尔排序 三、选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序 八、计数排序 稳定性结论 稳定性:排序后相同元素之间的相对顺序是否保持不变。 一、直接插入排序 基本思想:通过构建有序序列&#xff…...

mmdetection:图片推理以及将预测标签转换为YOLO格式标签

本文记录了使用 mmdetection 进行图片推理,并将推理结果坐标格式转换为yolo格式保存在txt中的代码。 文章目录 一、图片推理二、批量处理 一、图片推理 一个图片推理的demo。 import os import mmcv from mmdet.apis import init_detector, inference_detector fr…...

CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究

论文标题 An Empirical Study of Scaling Law for OCR OCR 缩放定律的实证研究 论文链接: An Empirical Study of Scaling Law for OCR论文下载 论文作者 Miao Rang, Zhenni Bi, Chuanjian Liu, Yunhe Wang, Kai Han 内容简介 本论文在光学字符识别&#xf…...

从混沌到秩序:Python的依赖管理工具分析

Python 的依赖管理工具一直没有标准化,原因主要包括: 历史发展的随意性:Python发展早期对于依赖管理的重视程度不足,缺乏从一开始就进行统一规划和设计的意识 社区的分散性:Python社区庞大且分散,众多开发…...

【系统】Windows11更新解决办法,一键暂停

最近的windows更新整的我是措不及防,干啥都要关注一下更新的问题,有的时候还关不掉,我的强迫症就来了,非得关了你不可! 经过了九九八十一难的研究之后,终于找到了一个算是比较靠谱的暂停更新的方法&#x…...