I have been using the resource editor in Visual C++ for a while to create programs in multiple languages. It works great and is very easy to use. But it is quite hard to keep all languages synchronized. For example, if you upgrade your program and add a control, you will probably need to add it in other languages as well. This is easy, if you remember to do it :-). To solve this, I created a tool that compares two resource-files (.rc) and notices if something doesn't look right (like missing controls, different window styles...).
Using the program
RC is quite straightforward to use. Select the two files you want to compare, and click on Compare. After a couple of seconds is the comparing done and you see the result. If you have resources in multiple languages in a file and just want to read a specific language, write the language string in the language boxes (like
LANG_ENGLISH for English). Leave this empty if you want to read all languages.
In the bottom of the window are error messages if the program fails to parse the files. Detected languages will also be found here.
Another feature of the program is that it could extract all strings from a file. This is very useful if you want to spell check your program, just click on "Make string list" and copy the log to a word processor. Only "File 1" will be used in this function.
If you want to see all resources in "File 1", click on "Make resource tree". If you uncheck "Only IDs", then you will also see all settings that the program has found (like strings, style of controls).
The fourth button, "Translation table", creates a table where you see how strings are translated. If you check "LocalizeRC INI", the output will be written as an INI-file to use with LocalizeRC (another program at CodeProject).
What it checks
Resource Comparer checks these:
- Settings (Checked, Grayed...)
- Structure (Order of items)
- Style settings (Border, system menu...)
- Extended style settings (Tool windows, client edge...)
- Tab order
- Type (So controls with same ID are of the same type)
- Style settings
- Extended style settings
- Help ID
The program does not check:
- Data (strings) in combo boxes
- Size of bitmaps, toolbars, icons or cursors.
Note: The program will fail to parse the file if you are using condition settings on the resources.
Checking strings could be very important. The program gives you five methods to use:
Don't check strings.
- Check %-words
Let's say you have a string like this: "Your name is: %s". You use this string with
CString::Format to replace "%s" with the user name. Then it is very important that in all other languages, the string also includes "%s". If it's not, then your program will probably crash when it runs
CString::Format. Therefore, check the program that all strings have the same number and order of %-words. So, if you have a string like "%s, %d" in one file, and another string like "%d, %s" in a second file, then you will get an error message.
- Check \-characters
This is very similar to (2). Let's say you have a string like this: "Hello\nworld". Then you translate it, and make a little error: "Hello\world" (no, they are not the same - look again!). It is very easy to make mistakes like that; I have done it myself several times. But now, I have this program that will warn me if I do it again :-).
- %- and \- problems
Uses both test 2 and test 3.
- Compare full string
This checks if strings match completely. This is useful if you want to see what changes you have done from an old version.
All strings are running this test, also string in dialogs and menus.
As a programmer, I know that it is more interesting to look on an example than reading a manual, so let us look on a log:
Comparing menu resource: IDR_MAINFRAME
Different style in ID: ID_FILE_CHECKED (1: CHECKED, 2: )
Different menu structure. Item 4 is ID_FILE_SAVE in 1,
and ID_FILE_SAVE_AS in 2
Different menu structure. Item 5 is ID_FILE_SAVE_AS in 1,
and ID_FILE_SAVE in 2
Comparing toolbar resource: IDR_TOOLBAR1
Different toolbar structure. Item 1 is ID_FILE_NEW in 1,
and ID_FILE_SAVE in 2
Different toolbar structure. Item 2 is ID_FILE_SAVE in 1,
and ID_FILE_NEW in 2
Comparing dialog resource: IDD_ABOUTBOX
String error in IDOK: Different number of %-signs ('OK', 'OK - %s')
Comparing dialog resource: IDD_TEST_DIALOG
Dialog style doesn't match ( DS_MODALFRAME|WS_POPUP|
Different style settings on control ID: IDC_LISTCONTROL
Couldn't find control ID: IDC_STATIC_EXTRA
Different items count (6 in 1, 5 in 2)
String error in IDS_TOFORMAT: Different %-words (%s and %d)
String error in IDS_SLASH: Different number of \-signs
String error in IDS_ULTRA: Different %-words (%s and %d),
Different \-characters (\r and \n)
Couldn't find bitmap: IDB_BITMAP_EXTRA in file 2
Couldn't find icon: IDI_ICON_EXTRA in file 2
Couldn't find cursor: IDC_CURSOR_EXTRA in file 2
As you can see, we have checked menus, toolbars, dialogs, strings, bitmaps, icons, and cursors. In the menu section, we see that in one of the files, one menu item is checked, in the other it's not. Two menu items also have swapped places.
In the toolbar section, the buttons
ID_FILE_SAVE have swapped places.
In the dialogs, there are several errors. The button
IDOK in the about box has a percent sign in the second file, but in the first, there is none. In the other dialog, we see that the dialog has different styles in the two files. The list has the "Owner draw" value in the first file, but not in the second. We are also missing a control in the second file,
IDC_STATIC_EXTRA. Therefore, we do not have the same number of controls in the two files.
We have problems with three strings. In
IDS_TOFORMAT, we are using "%s" in the first file, and "%d" in the second. In the string
IDS_SLASH, there is a misspelling, \\ should be \n. In the last, we have a string that has both types of errors.
We also see that we are missing a bitmap, icon, and a cursor in the second file.
Points of Interest
There is a special ID you can use to have multiple number of items with the same ID,
IDC_STATIC (this is the default ID for new static text controls). When Resource Comparer compares dialog controls, it compares items with the same ID. So when more than one control has the same ID, we have a problem. Resource Comparer solves this by using the tab order to figure out how to match the controls. The first control with
IDC_STATIC will be compared with the first control with the same ID in the other file. And the second control will be compared with the second control in the other file, and so on.
If you look at the code, you may see that I have written it quite fast. But it seems to work well and is enough for me. Parsing the resource files was the hardest thing to do. The program makes a lot of assumptions but it seems to be clever enough :-). As I said before, conditions are not supported. When you use conditions,
#if statements are added in the file, and I haven't cared about this. But if you are interested to solve this problem, just go for it :-). And I know the output could be better, but since I will not use this program very often, I really don't care about this.
Unicode is supported, but not multi-byte characters in ANSI.
I have only tested this program on projects made in VC6, but I don't think there should be any problems with later versions.
- 21 August, 2004 - Version 1.2. Support for Unicode. Applied a minor fix by Graham Pye. Captions in dialogs are now tested.
- 4 August, 2004 - Version 1.1. "Help ID" is now checked on controls. Controls with ID
IDC_STATIC are now compared. If more than one control has this ID, the tab order will be used to figure out how to match them. The program can now create INI files to use with RC Localization Tool
- 10 July, 2004 - Initial version.