首页 > 编程知识 正文

mfc7360改中文,mfc多线程编程实例

时间:2023-05-04 05:38:14 阅读:114435 作者:1870

这10天来,我一直忙于在mfc中文版程序中支持其他语言的设置。 用我使用的stringtable实现了。 这个方法比较简单高效,但实现起来有点无聊。 昨天晚上刚刚忙碌结束,今天总结实现过程的关键。

1、stringtable。

字符串表在这里主要用于翻译。 例如,对话框中的caption、控件中的窗口文本和MessageBox提示可以将已翻译的内容添加到与每种语言对应的字符串表中。

(1)先添加字符串表。

如果当前项目中没有字符串表,请选择该项目,右键单击,然后选择“添加”----“资源”---“字符串表”----“新建”。

如果当前项目包含字符串表,请切换到“资源”视图,选择字符串表,右键单击,选择“插入副本”,然后选择要添加的语言的字符串表。 字符串表,用于插入的新副本。 在以前的stringtable的复制版中,翻译了内容。

(2)在stringtable中添加或修改内容。

在中文字符串表中添加以下内容:

在英语字符串表中添加以下内容

如果stringtable是从另一种语言的stringtable复制的,直接翻译,修改内容即可。

2、在代码中设置控件语言。

控件所属对话框的类成员函数OnInitDialog ) )中,设置属于该对话框的控件的内容,如“确认”“取消”按钮和添加到对话框中央的静态文本框。 如果控件ID分别为IDOK、IDCANCEL和ID_STATIC,则代码如下所示:

CString strLoad; STload.loadstring(BTN_ok ); getdlgitem(idok )-setwindowtext ) strload; //用于设置“确认”按钮上显示的内容STload.loadstring(BTN_cancle )的getdlgitem(idcancel )-setwindowtext ) strload; //设置“取消”按钮上显示的内容strload.loadstring (static _ content )的gtdlgitem(id_static )-setwindowtext ) str load; //设置静态文本框中显示的内容

3、设置线程和UI的语言。

在theApp类对象所属的类成员函数initInstance ()中设置线程和UI语言。 函数如下:

语言语言=setthreaduilanguage (make lcid ) makelangid ) lang_English、SUBLANG_ENGLISH_US、SORT_DEFAULT ) //将线程UI语言设置为英语setthreadlocale(idlang )//设置线程语言和UI语言的匹配

语言语言=setthreaduilanguage (make lcid ) makelangid ) lang_chinese、SUBLANG_CHINESE_SIMPLIFIED )、 将sort_deeed //线程UI语言设置为中文setthreadUIlocale(idlang )//匹配线程语言和UI语言并设置线程和ui语言后,执行步骤2中的cstring.loadstring ()

现在,您已经实现了设置语言的基本功能。 效果如下。

将语言设置为英语时:

将语言设定为中文时:

现在,实现mfc程序多语言设置的工作已经基本完成,但在具体实施中,还出现了以下问题:

1、设置MessageBox按钮的语言。

刚开始设定多语言的时候,在网上查了很多资料,据说确认取消MessageBox的按钮的语言会根据系统语言而变化,不能自己设定。 之后,我的大师说消息盒Ex可以实现。 例如,我关闭对话框时,会发出“是否确认要关闭对话框”的信息,实现以下功能。

(1)在中英两个字符串表中添加提醒:

中文字符串表:

英语字符串表

)2)对话框的OnClose ) )在消息中添加消息处理:

CString strLoad; str load.loadstring (msg _ box _ close ); intiret=messagebox ex (空,strLoad,L'Warn ',MB_OKCANCEL | MB_ICONWARNING,GetThreadLocale ) ); if(iret=

= IDCANCEL){ return;}

设置为中文时:

 

设置为英文时:

 

可以看到,只要我们设置了MessageBoxEx函数的最后一个参数,就可以切换MessageBox中的确认取消按钮的语言,但MessageBox的提示内容和标题,还得自己在stringtable中添加,然后在代码中设置。

 

2、菜单。

菜单实现多语言,跟stringtable类似,在资源里,选择该菜单,右键,“插入副本”,然后选择要添加的语言,添加后,直接在菜单上翻译就行。我们在代码里设置了线程和UI语言后,程序会根据设置的语言,自动选择相应语言的菜单。

如果想在代码里动态的修改菜单语言,代码如下:

CMenu*pMainMenu = CMenu::FromHandle(m_wndMenuBar.GetDefaultMenu());if(pMainMenu != nullptr){ CString strLoad; //修改一级菜单,比如文件,工具,视图,设置等 strLoad.LoadString(MENU_FILE); pMainMenu->ModifyMenu(0, MF_BYPOSITION | MF_STRING, 0, strLoad);//修改一级菜单的第一项 strLoad.LoadString(MENU_EDIT); pMainMenu->ModifyMenu(1, MF_BYPOSITION | MF_STRING, 0, strLoad);//修改一级菜单的第二项 //以此类推,修改一级菜单的第几项,就将ModifyMenu的第一个参数设置为从0开始的索引值,只要不用响应消息,第三个参数就为0;需要响应消息的话,就必须传入菜单对应的控件ID //... //修改一级菜单第一项的子菜单(也就是二级菜单),比如文件菜单下的新建文件,打开文件,保存文件,等等 CMenu*pSubMenu = pMainMenu->GetSubMenu(0); if(pSubMenu != nullptr) { //注意,此时的菜单是需要响应具体消息的,所以ModifyMenu的第三个参数,必须是实际的菜单按钮的ID值,因为消息映射里,消息影响函数是和控件ID绑定的 strLoad.LoadString(MENU_OPEN_NEW); pSubMenu->ModifyMenu(0, MF_BYPOSITION | MF_STRING, IDC_MRU_FILE_NEW, strLoad); strLoad.LoadString(MENU_OPEN_FILE); pSubMenu->ModifyMenu(1, MF_BYPOSITION | MF_STRING, IDC_MRU_FILE_OPEN, strLoad); }}//下面这行代码很重要,只要修改了主菜单,必须在修改后加上这行,不然菜单更新不及时m_wndMenuBar.CreateFromMenu(pMainMenu->GetSafeHmenu(), TRUE, TRUE);pMainMenu.Detach();

需要注意的是,菜单里的横线也是占据一个索引项的,比如:

注意索引为3和5的横线。

3、多线程的问题。

前面我们也看到了,MFC设置语言,是以线程为单位来设置的,所以需要在每个线程里,都通过调用SetThreadUILanguage和SetThreadLocale设置语言。如果发现某些地方的语言设置没起作用,就先检查是否在该线程中设置了语言。

4、资源访问问题。

如果引用了dll模块,在dll中需要使用dll自带的stringtable资源,那么在LoadString时最好指定dll的资源句柄。

获取dll的资源句柄有两种情况:如果该dll有dllMain函数,该函数的第一个参数就是该dll的资源句柄,将该句柄传给LoadString的第一个参数即可。如果没有dllMain函数,就在该dll的app的initInstance函数中添加如下代码:

HINSTANCE g_instance;BOOL testDllApp::InitInstance(){ CWinApp::InitInstance(); AFX_MODULE_STATE* state = AfxGetModuleState(); g_instance = state->m_hCurrentInstanceHandle; return TRUE;}

然后将g_instance传给LoadString的第一个参数即可。

 

以上就是我实现mfc程序设置多语言功能的总结。上述代码都是一字一字在网页里编辑的,可能会有手误,望见谅。

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。