首页 > 焦点 > 简单实用资源DLL与语言选择菜单的实现
简单实用资源DLL与语言选择菜单的实现
网上收集 2007/11/26 17:05:51 (206)
 在当今这个发展越来越快的世界中,软件的本地化及翻译工作越来越重要,极大地关系到软件的销量及普及率;就拿常见的Win32/MFC程序来说,一个比较方便的办法就是附加单独的资源DLL文件。

  本文介绍了一种易于应用的方法,可在C++/MFC程序中支持多种语言,并演示了怎样用少量的代码添加对资源DLL的支持,这包含了两个方面:根据用户偏好在程序开始时自动选择最合适的语言;提供一个语言选择子菜单(以供用户自行选择)。

  关于资源DLL

  有关在程序中支持多语言最灵活的方法,也许就是使用所谓的“资源DLL”了,其主要思想是为每种语言创建一个单独的DLL文件,而这个DLL中包含了已翻译为某种特定语言的程序资源;因此,如果你的程序最初版本是中文,且又翻译成了法文、德文、日文,这样你就有了三个资源DLL。中文资源在.exe文件中,而其他三种语言各自对应一个DLL文件。

  如果程序中又需要支持某种新的语言,只须简单地添加一个DLL到安装文件中就行了。在程序运行时,会根据用户偏好,相应地加载资源DLL。

  资源DLL可由一个专门的Visual Studio工程来创建,也可由某些专用的工具来创建,本文以Visual Studio 2003来创建,Visual Studio 2005也差不多。顺便提一下,把所有的语言资源都打包进EXE文件,在理论上是可行的,但在实际中却行不通;因为,大多数加载资源的高层API——如LoadString()、DialogBox()等等——不会让你指定想要的语言,而SetThreadLocale()也不会如预期那样工作(此API在Win9X中不存在)。

  一步一步支持资源DLL

  以下是在主程序中,添加支持资源DLL(语言选择菜单)的步骤:

  1、 把LanguageSupport.h及LanguageSupport.cpp添加到你的工程。

  在MyApp.h及MyApp.cpp(假定CMyApp是工程类)中,加入以下黑体行:

以下是引用片段:
#include "LanguageSupport.h"
  class CMyApp : public CWinApp
  {
  public:
  CLanguageSupport m_LanguageSupport;
  ...
  };
  BOOL CMyApp::InitInstance()
  {
  //把以下这行注释掉,防止MFC进行自己的资源DLL处理。
  // CWinApp::InitInstance();
  ...
  SetRegistryKey(_T("MyCompany"));
  //根据用户偏好,加载相应的资源DLL。
  m_LanguageSupport.LoadBestLanguage();
  ...
  }

  在主菜单中,添加一个名为“语言(Language)”的菜单项。接下来,在CMainFrame类中,为“语言(Language)”菜单项添加一个菜单更新处理程序,假定名为OnUpdateToolsLanguage(),如下所示:

以下是引用片段:
void CMainFrame::OnUpdateToolsLanguage(CCmdUI *pCmdUI)
  {
  //创建语言子菜单(只在菜单第一次打开时)。
  theApp.m_LanguageSupport.CreateMenu(pCmdUI);
  }

  2、 为语言选择菜单项添加菜单处理程序。

  在MainFrm.h中,把处理程序afx_msg void OnLanguage(UINT nID)添加在CMainFrame的protected部分中某处;在MainFrm.cpp中,添加定义及消息映射入口:

以下是引用片段:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  ...
  ON_COMMAND_RANGE(ID_LANGUAGE_FIRST,ID_LANGUAGE_LAST, OnLanguage)
  //这些ID声明在LanguageSupport.h中
  END_MESSAGE_MAP()
  void CMainFrame::OnLanguage(UINT nID)
  { //用户选择了菜单中的某种语言
  theApp.m_LanguageSupport.OnSwitchLanguage(nID);
  }

  注意,这个处理程序不能用向导来添加,因为它是一个COMMAND_RANGE菜单处理程序——用于处理“语言(Language)”菜单中所有语言项。

  3、 也是最后一步,在字符资源表中,添加一个名为IDS_RESTART的字符串,值为“请重新运行%1”,%1可为程序名。

  怎样创建资源DLL

  首先,CLanguageSupport类假定所有的DLL都名为MyAppXXX.dll,这里MyApp.exe是可执行文件名,XXX是所支持语言的三个字母缩写(CHN代表中文、FRA代表法文、DEU代表德文、JPN代表日文)。同时,exe文件与dll文件都应有一个Version版本信息资源,其语言匹配文件名中的三个缩写字母。接着,我们创建一个Win32 DLL工程:

  1、 打开Visual Studio 2003,选择文件-新建-工程,输入工程名如MyAppDEU创建一个德文版本,单击确定;在程序设置页,选择DLL及空项目。

  2、 把它转换为一个资源DLL:打开项目属性,在“配置”下拉框中选择“所有配置”;打开链接器-高级,将“纯资源DLL”设为“是”。另外,如果你使用Visual C++ 6.0,则需要手工在链接设置的编辑框中添加 /NOENTRY作为命令行选项;而Visual C++ 2005,与Visual C++ 2003类似,在链接器-高级里,选择“无入口点”为“是”。

  3、 创建一份EXE资源文件的副本,并把它添加到DLL工程中:建议将MyApp.rc文件改名成所需的语言版本,如MyAppDEU.rc。

  4、 修改路径:在资源视图中,鼠标右键单击MyAppDEU.rc,打开“资源包含”,修改所有包含资源文件的路径。每种语言都有会一个子目录l.xxx,例如,修改#include "afxres.rc"为#include "l.deu\afxres.rc"。

  5、 设置语言属性:在资源视图中,打开“版本信息version info”(如果没有就创建一个),设置语言属性为正确的语言,如German(Germany),确保语言匹配DLL名中的三个字母。

  现在可以编译DLL了,之后便可得到一个资源DLL,当然,它还没有经过翻译,但这已是翻译者的任务了。按照上述步骤就可创建出一系统语言的DLL,你唯一要做的事情,就是把它们复制到应用程序的目录了。另外,从程序中加载资源DLL也非常简单,LoadLibrary()与AfxSetResourceHandle(hDll)就可以胜任了。

 以下是源代码:

以下是引用片段:
LanguageSupport.h
  #pragma once
  #include 
  #define ID_LANGUAGE_FIRST 0x6F00
  #define ID_LANGUAGE_LAST 0x6FFF
  class CLanguageSupport
  {
  public:
  CLanguageSupport();
  ~CLanguageSupport();
  void CreateMenu(CCmdUI *pCmdUI, UINT nFirstItemId= ID_LANGUAGE_FIRST);
  void OnSwitchLanguage(UINT nId, bool bLoadNewLanguageImmediately= false);
  void LoadBestLanguage();
  protected:
  CWordArray m_aLanguages;
  LANGID m_nExeLanguage;
  LANGID m_nCurrentLanguage;
  HINSTANCE m_hDll;
  static const TCHAR szLanguageId[];
  static LANGID GetLangIdFromFile(LPCTSTR pszFilename);
  static CString GetLanguageName(LANGID wLangId);
  static LANGID GetUserUILanguage();
  static LANGID GetSystemUILanguage();
  void GetAvailableLanguages();
  bool LoadLanguage();
  bool LoadLanguageDll();
  void LookupExeLanguage();
  void UnloadResourceDll();
  static void SetResourceHandle(HINSTANCE hDll);
  };
  LanguageSupport.cpp
  #include "stdafx.h"
  #include
阅读(206) (责任编辑:城市网)
关于我们 - 联系我们 - 网站荣誉 - 广告服务 - 版权声明 - 网站地图
Copyright© 2007-2018 bj1.com.cn 首都热线 版权所有 QQ:165687462
中国·北京 粤ICP备14047004号-20