Click here to Skip to main content
Email Password   helpLost your password?

Contents

Introduction

When I planned to release my shareware project in other languages, I searched for a simple but powerful tool which was able to create localized Resource Scripts (RC files). I didn't find any and so I started developing my own tool.

This tool, called LocalizeRC, scans Resource Scripts and extracts the language specific strings into an INI file. This file can be edited with any text editor. It then creates a new Resource Script with the translated strings from the INI file.

Background

Although there is a lot of commercial software for translating resource files, I started developing LocalizeRC, because the other tools are all very complex and also very expensive. LocalizeRC is very easy to understand and makes it possible to create a translation within minutes! To supply more than one language just create a resource-only DLL from the Resource Script, which is created by LocalizeRC. The only disadvantage of LocalizeRC is that you have to compile the Resource Script for yourself. I will explain later, how to manage that.

Using the tool

First of all you have to create a software program in one language, like you normally do. All your translations start from this original language. My first language is always English, although I'm from Germany, because it is easier to find someone who is able to translate from English to his native language, than from German. But that is up to you...

Then you can start LocalizeRC and create a new workspace within a new folder (e.g. "German") by clicking on New.... As Input RC you should select the Resource Script in original language. For the Language INI and Output RC you should specify any filename for these files within the workspace folder (e.g. "German.ini" and "German.rc"). You can also choose any other folder but I recommend to have these three files in the same folder for reasons of clearness. Then click on the Create/Actualize INI from Input RC button.

Afterwards you can edit your Language INI with your standard editor by clicking the Open INI for Edit button. In the INI file there are two items per line. On the left side of the equals sign stands the original language. The rights side has to be replaced by the new language. You can also deploy this INI file to external translators. In the section [code_page] in the INI file, you can set the codepage that should be used in that RC. For a list of valid codepages look have a look at Links.

When you have finished translating the strings just save that INI file and close the editor. In LocalizeRC you should also check the option Copy Resource Header and "RES" Folder. Then the header "resource.h" and the files within the subfolder "RES" will be copied to the new folder which will later contain the Output RC. Afterwards you should click on the Create Output RC with INI button. Then LocalizeRC automatically creates the Output RC with the translated strings.

If you want to translate to Asian languages, you must perhaps use Unicode RCs, because some of these languages have more than 128/256 characters. Then you have to download the Unicode binary. Please notice that only Windows NT/2000/XP is fully compatible with Unicode.

As a result you should have created a folder with four files and one subfolder:

To use these files in your application, you have to create a resource-only DLL.

Create a resource-only DLL (satellite DLL)

I describe these steps for Visual C++.NET (7.0 or 7.1), but it should be very similar in 6.0 and 5.0.

If you have got a MFC application, it will automatically load a satellite DLL if it has the filename ApplicationNameXXX.dll. The ApplicationName should be same name your application has (the filename without the extension .exe) and the XXX is a three-letter language code. MFC attempts to load the resource DLL for each of the following languages in order, stopping when it finds one:

If MFC does not find any satellite DLLs, it uses the resources which are contained in the application itself (independent from the language). To load a language DLL manually, do the following steps before loading any dialog (e.g. in InitInstance). Call LoadLibrary for your language DLL then call AfxSetResourceHandle to make MFC loading all resources from that DLL. At application exit you have to free the language DLL via FreeLibrary.

For an example you can look at the source code of LocalizeRC.

Multiple languages within one file

After getting some mails why not including more than one language into one Resource Script and also into one EXE/DLL I will try to explain it here. In old Windows systems (Windows NT/9X/ME) there was an automatic selection of the right language, if more than one language was available in one EXE/DLL. This selection works in most of the cases. But in modern Windows systems (Windows 2000/XP/2003) this automatic selection doesn't work any more because of internal changes (for more information read the KB article 300680). Microsoft recommends to pack only one language into one file and so do I. Even in Windows NT/9X/ME there is no simple solution to override the automatic selection by the OS.

ANSI versus Unicode

LocalizeRC can either create ANSI or Unicode Resource Files (RCs). Because Windows 9X/ME doesn't fully support Unicode, you can only use the ANSI format with these Operating Systems. The Binary is different for these two versions. Please download the appropriate version or build them yourself.

ANSI files create strings with one byte for each character. That means that you can only store up to 256 different characters. That is enough to store the latin alphabet, but not enough for many other languages which uses much more characters. Therefore you need the Unicode format.

Unfortunately Visual Studio up to the current version 2003 isn't able to edit Unicode Resources. It only says: "Opened in another editor." However you can compile those resources without problems. So you must edit the RCs either with Notepad or another editor which is able to read and write Unicode. You find an example about Handling of Unicode Resources at the MSDN Library in the Links section.

Links and Miscellaneous

General

MSDN Library

CodeProject

I want to make LocalizeRC a real open-source software. Please send your additions/modifications and bugreports as well as typos in the website and the program to webmaster@wincd.de. Also send your wishes for the next version. Please supply me with your translation for LocalizeRC. A new icon would also be very nice ;-).

This is the preliminary Todo list for LocalizeRC:

This project is a thank to all the great authors and helpful developers at Codeproject!

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralAny new versions?
thready
4:17 17 Sep '09  
Hi Konrad,

Great software! I'm wondering if it has been updated elsewhere? You mentionned that you wanted to create open source software out of it.

Thank you!
Mike
GeneralMFC VS2005
sabdalla80
5:03 9 Feb '09  
I can't get this tool to work properly in VS2005 MFC. Does it not work with VS2005?
General[bug] error encoding reading dlginit data
moo.wejoin
0:13 23 Jun '08  
1. unicode program of LocalizeRC.exe
2. rc file is ucs-2le encoding, with bom character
when i open the rc file from LocalizeRC.exe as a source, every ascii and non ascii characters is fine, but non-ascii string in [dlginit] is wrong
[DLGINIT]
100;300;600;=100;300;600;
±?·?;Outlook;Outlook Express;Windows ?¨????;=±?·?;Outlook;Outlook Express;Windows ?¨????;

this piece of data comes from combobox, the dropdown list box
GeneralRe: [bug] error encoding reading dlginit data
moo.wejoin
0:21 23 Jun '08  
btw, the data is in gbk encoding while the rc file is ucs-2le encoding
General[bug] error reading localized rc file as ansi mode
moo.wejoin
0:10 23 Jun '08  
1. using either ansi/unicode program of LocalizeRC.exe
2. rc file is GBK encoding
when i open the rc file from LocalizeRC.exe as a source, every non ascii characters goes wrong.
GeneralHow do I update dll if main app changes ?
worksopbenny
21:34 14 Oct '07  
I just tried out your localiser app Konrad and all seems to be working OK - now I just have to translate the ini file. But I just realised there may be problems if I update my base application, e.g. add another dialog. The base app resource file will change, so I could produce another ini file, but if I do this within localiserRC this will overwrite the ini file I have manually edited. So how can I produce an updated translator resource file without losing all my ini file edits - other than saving old file, cut and paste etc.
GeneralRe: How do I update dll if main app changes ?
thready
4:10 17 Sep '09  
worksopbenny wrote:
I just tried out your localiser app Konrad and all seems to be working OK - now I just have to translate the ini file. But I just realised there may be problems if I update my base application, e.g. add another dialog. The base app resource file will change, so I could produce another ini file, but if I do this within localiserRC this will overwrite the ini file I have manually edited. So how can I produce an updated translator resource file without losing all my ini file edits - other than saving old file, cut and paste etc.

Hi - did you ever get a response to this? Did you still use this app in the end? (ever find something better that was still free?).

Thanks!
Mike
GeneralLoosing dialog modifications after update
Ruben Jönsson
2:58 31 Jul '07  
Hi Konrad and thanks for a great program.

I have been using it for a while and now I am now in the process of updating some software and its language resource DLLs. When I add new texts to my main resource file and update the ini from that and then create the new rc files for the additional languages I loose all control adjustments I have done to accomodate for different text lengths.

I see that you have planned to do a fix for this in your ToDo list. The support for different fonts is also a welcome feature.

Since these are such great features, I just have to ask if they will be done in the near future?

Anyway, thanks again for a very useful piece of software.

/Ruben



Questioncodepage for Hindi etc
c_srishti
12:59 19 Apr '07  
I am trying to use this nice tool to translate my software to Hindi. MS says that there is no codepage for Hindi.....etc...Armenian & Georgian. When I put 0 or 1 for the code page in the ini file I am getting errors in the VC++ when I open the Output RC or when I try to compile the satellite dll:
0: Code page is not an integer
1: Invalid Code page.

Has anyone had a similar trouble?
Thanks a lot for any help
Srishti
GeneralV1 & V2 (beta) don't understand RC2 resource files
-273C
2:15 27 Oct '06  
Great program but I have a MFC project with the standard resource file (.rc) but also additional nested resource files (See: MFC Library Reference TN035: Using Multiple Resource Files and Header Files in Visual C++).

It would be very nice if LocalizeRC would understand and process all these as well and using the same directory structure for the results.

PS. I can't get LocalizeRC V2 Beta to compile cleanly under VS2005 (VC8). Has anyone?
GeneralLocalizeRC v2 ?
.dan.g.
23:12 1 Oct '06  
Hi konrad

Has there been any further progress towards LocalizeRC v2?

The last time we spoke you were getting close but I've not heard anything since. I'm still very interested in assisting in any way I can so that users of ToDoList[^] can begin translating.

Regards

.dan.g.

AbstractSpoon Software abstractspoon2_at_optusnet_dot_com_dot_au

GeneralRe: LocalizeRC v2 ?
Konrad Windszus
1:31 3 Oct '06  
Hi Dan, since I'm very busy at the moment, currently there is not much progress with LocalizeRC 2. But I try to release version 2 at the end of october, because there are only very few bugs left. Thanks for your patience. I will notify you, as soon as there is any news.

Regards
Konrad
GeneralRe: LocalizeRC v2 ?
-273C
12:37 19 Oct '06  
Hi,

Will V2 build with no errors or warnings under VC8 (VS2005)?

Currently there are warnings that
CFileException::generic
is depreciated and is replaced by
CFileException::genericException
and it also complains with:

C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include/afxres.h(28) : warning RC4005: 'IDR_MANIFEST' : redefinition

Looks like a good tool though.

David

GeneralRe: LocalizeRC v2 ?
.dan.g.
12:34 20 Nov '07  
Konrad

I would be happy to help out getting LocalizeRC ready for release if that would improve it's chances.

Or, and I know this is a big ask, could you send me the sourcecode so that I could use it privately?

Regards

.dan.g.

AbstractSpoon Software abstractspoon2_at_optusnet_dot_com_dot_au

GeneralBreakage fix
emilytzgyr
2:30 18 Jul '06  
Hi,

this great tool breaks with an access violation when updating .ini files in case one section is removed from the original .rc file.

Here is the patch:

--- LocalizeRC_src/IniEx.cpp	2004-01-12 14:44:26.000000000 +0100
+++ LocalizeRC_src_new/IniEx.cpp 2006-07-18 13:13:10.078125000 +0200
@@ -633,6 +633,13 @@
m_Keys[nIndex]=NULL;
m_Values[nIndex]=NULL;

+ for (int i = nIndex+1; i < m_allocatedObjectCount; i++) {
+ m_Keys[i-1] = m_Keys[i];
+ m_Values[i-1] = m_Values[i];
+ }
+ m_Keys[m_allocatedObjectCount-1] = NULL;
+ m_Values[m_allocatedObjectCount-1] = NULL;
+
m_Sections.RemoveAt(nIndex);
m_SectionNo--;
m_Changed=TRUE;

GeneralA tool for merging a localization from one xml file with another
yarus24
4:33 21 Jun '06  
Hi,

You know that http://www.wincd.de/LocalizeRC.zip uses XML files.

I found that when several users try to make a localizations at the same time - I need a tool to combine these xml files. So I have written it in xslt. It is not an edge in xslt programming (my second xslt sheet) and it took 3 days to write and debug.

You can use msxml and write a wrapper for it in vbs or js, I have used Saxon for windows.

You can integrate it into this wonderful utility, for example by writing some simple wizard for copying a language from one xml file to another.

Feel free to use it anywhere, it is a public domain.

To use it you need to define two parameters:
1. A file form which you want to extract a language:
<xsl:variable name="source" select="document('dutch.xml')" />
2. name of a language:
<xsl:variable name="langToReplace" select="'NLD'"/>

<code>
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0" >

     <xsl:output method = "xml" indent = "no" />

     <xsl:variable name="source" select="document('dutch.xml')" />
     <xsl:variable name="langToReplace" select="'NLD'"/>

     <xsl:template match="/">
          <rcxml>
               <xsl:copy-of select="//rcoptions"/>
               <xsl:apply-templates select="//rclanguages"/>
               <xsl:apply-templates select="//rcsection"/>
          </rcxml>
     </xsl:template>

     <xsl:template match="//rclanguages">
          <rclanguages>
               <xsl:copy-of select="rcinput"/>
               <xsl:variable name="r1" select="$source/rcxml/rclanguages/rcoutput"/>
               <xsl:variable name="r2" select="rcoutput"/>

               <!-- copy keys   from   external xml file -->
               <xsl:copy-of select="$r2" />
              
               <!-- copy keys that are missed in external xml file -->
               <xsl:for-each select="$r1[not(@lang = $r2/@lang)]">
                    <xsl:variable name="item" select="."/>
                    <xsl:copy>
                         <xsl:copy-of select="@*|node()"/>
                    </xsl:copy>
               </xsl:for-each>
          </rclanguages>
     </xsl:template>

     <xsl:template match="//rcsection">
          <xsl:copy>
                      <xsl:copy-of select="@*"/>
               <xsl:variable name="name" select="@name"/>
               <xsl:for-each select="./rcitem">
                    <xsl:copy>
                                <xsl:copy-of select="@*"/>
                         <xsl:for-each select="./rcstring[not(@lang = $langToReplace)]">
                               <xsl:copy>
                              <xsl:copy-of select="@*|node()"/>
                               </xsl:copy>    
                         </xsl:for-each>
                         <xsl:variable name="idmain" select="@id"/>
                         <xsl:variable name="r0" select="$source/rcxml/rcsection[@name = $name]/rcitem[@id = $idmain]"/>
                         <xsl:copy-of select="$r0/rcstring[@lang = $langToReplace]"/>

                         <xsl:for-each select="./rcitem">
                              <xsl:copy>
                                          <xsl:copy-of select="@*"/>
                                   <xsl:variable name="id" select="@id"/>
                                   <xsl:for-each select="./rcstring[not(@lang = $langToReplace)]">
                                         <xsl:copy>
                                             <xsl:copy-of select="@*|node()"/>
                                              </xsl:copy>    
                                   </xsl:for-each>
                                         
                                   <xsl:variable name="r" select="$source/rcxml/rcsection[@name = $name]/rcitem[@id = $idmain]/rcitem[@id=$id]"/>
                                   <xsl:variable name="tocopy" select="$r/rcstring[@lang = $langToReplace]"/>
                                   <xsl:copy-of select ="$tocopy"/>
                              </xsl:copy>
                         </xsl:for-each>
                    </xsl:copy>
               </xsl:for-each>    
          </xsl:copy>
     </xsl:template>

     </xsl:stylesheet>

</code>

Dmitry Yakimov
Generalstat() failes for Japanese filename with the long path
Sandeep. Vaidya
3:57 23 Mar '06  
I using Win2K Japanese. I have created a file with maximum path size allowed by the windows using the Japanese characters in file name. If I use stat() for that file, it failes and return -1.

If I Get the file descriptor by using the open function and use fstat() it succeedes.

Please let me know what coult be the problem.

Thanks in advance.
Sandeep
GeneralRe: stat() failes for Japanese filename with the long path
Konrad Windszus
9:52 23 Mar '06  
The normal stat function takes a normal pointer to char as parameter. For the Japanese characters you should use the Unicode-version of stat: wstat, which takes a pointer to wchar as parameter. You find more information about Unicode in the article http://www.codeproject.com/cpp/unicode.asp[^].

Regards
Konrad
GeneralRe: stat() failes for Japanese filename with the long path
Sandeep. Vaidya
20:16 23 Mar '06  
It is not the wchar. String is in multi byte. stat support multi byte. That is what the MSDN says. same stat works fine for the short path file. If I use the same set of characters with short path, stat return success. I have taken the maximum possible length allowed by the Win2K for the creation of the file.

It failes for this file.


GeneralRe: stat() failes for Japanese filename with the long path
Konrad Windszus
21:23 23 Mar '06  
Then I can only guess: Is the pathname longer than 255 bytes? Probably stat can only handle filenames up to 255 characters (bytes for multibyte strings). Just test it with a filename at the limit and check the result, then append one more character and check again. Perhaps the errno does also help in case of failure.
Regards
Konrad
GeneralRe: stat() failes for Japanese filename with the long path
Sandeep. Vaidya
22:11 23 Mar '06  
Even I guess the same. stat stops working after some set of characters. I used strlen()and came to know that it stops working after 311.

Windows supports file path with max 256 character but not 256 bytes. In case of Japanese OS also it supports 256 japanese chars which means much more than 256 bytes. I think that is the problem. Cry

Thanks for your replies.
GeneralCommandline execution
.dan.g.
20:09 8 Mar '06  
hi konrad

the more i think about using this app the more i like the idea of giving it commandline support. ie run it without a UI by providing all the input via the commandline. this way i can setup a batch file to refresh the ini files of a whole bunch of different languages and rebuild the dlls in one hit. i haven't figured it all out yet but i'll notify you when i have in case you're interested.

[more]
even easier would be to add the workspace file to the VC6 project and then define a custom step that uses LocalizeRC to always refresh the ini file and generate the output files prior to building. i've just got to see if it can be done so simply. the trickiest bit is making sure that the workspace file is processed before anything else.Unsure
[/more]

.dan.g.

AbstractSpoon Software abstractspoon2_at_optusnet_dot_com_dot_au

-- modified at 1:12 Thursday 9th March, 2006
GeneralRe: Commandline execution
Konrad Windszus
21:03 8 Mar '06  
hi .dan.g.
I'm currently developing version 2.0 of LocalizeRC. You can find a beta version at http://www.wincd.de/LocalizeRC.zip[^]. This version uses XML files instead of INI files. Therefore you need MSXML 4.0 to run this program. Most computers do already contain a version of MSXML 4.0. If you get an error message during the start-up download MSXML from http://www.microsoft.com/downloads/details.aspx?FamilyID=3144b72b-b4f2-46da-b4b6-c5d7485f2b42&DisplayLang=en[^].
Please give me feedback on this new version (by e-mail since it is only a beta Wink ).

Regards
Konrad
GeneralRe: Commandline execution
.dan.g.
21:48 8 Mar '06  
when do you anticipate releasing it properly (not that i'm bothered about using a beta)?

will it have commandline support?

.dan.g.

AbstractSpoon Software abstractspoon2_at_optusnet_dot_com_dot_au
Generalexcellent
.dan.g.
1:07 8 Mar '06  
this looks like just tool for translating ToDoList[^].

many thanks.

.dan.g.

AbstractSpoon Software abstractspoon2_at_optusnet_dot_com_dot_au


Last Updated 15 Jan 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010