String table

I want to hold all visible strings for my project in a table, probably in a series of header files.  The aim is to replace IDC_MEMORY_ERROR with "You are out of memory".  How should I do this?  I would rather use something other than #define, but if that's the best way, then I can live with it.

It must work on any platform (so no VC++ resources etc.)
Who is Participating?
jkrConnect With a Mentor Commented:
Well, the simplest way would be to load your text resources at runtime from a text file into an array and have IDC_MEMORY_ERROR as an index into that array. If you want it to be bullet-proof, use a map that maps the integer constant to a string...
IainHereAuthor Commented:
With that method, I'd have to keep the strings in the same order, otherwise I'd have to recode the section that reads in the strings.  Is there a way for me to avoid it, or am I missing something?

Also, using #define will fix the strings at compile time - is there a special advantage/disadvantage to this?

My ideal would be to have a text file that read

IDC_MEMORY_ERROR    "you're outta memory"
IDC_BORED_ERROR     "you're too bored"

and refer to the IDC_ in the program.  Thanks for your help.
>>Also, using #define will fix the strings at compile
>>time - is there a special advantage/disadvantage
>>to this?

Well, there's a disadvantage: You'll have to supply a seperate binary for each language...
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

IainHereAuthor Commented:
Oh yeah - I forgot about that whole section in the install process "choose language".  As you might guess, this is my first go at multi-language support.

So, discounting that option, if I use the map solution, my file will look like

10001   "Error String"

and code will look like:
const int IDC_STRING_ERROR = 10001;

And I implement a method of equating the two.  Is this right?

How would you normally store strings for different languages?  Is it acceptable to put the strings in an unencoded file on the end user's machine?

Increasing points to 100.
>>Is it acceptable to put the strings in an unencoded file on the end user's machine?

I've seen that with several commercial products - just don't name them '*.txt', so the users don't tamper with them :o)

BTW, regarding the solution you mentioned - this is ideal for using a map, as a map also allows "gaps", IOW, doesn't require consecutive numbering...
>>Is it acceptable to put the strings in an unencoded file on the end user's machine?

anouther opption i have seen is placing your error codes in a dll resorce. you could write a function you pass an error code to and have it return the error string. all that would be required then would be a new dll for each language.

if you want to do something like this a map would be ideal for you.

and if you want to go that rought you could move all your text resorces to that file and worry about transltion later.
Actually we've implemented something like this.  We are parsing .rc files and all string resources into binary with it' numeric ids.  Then file translated (using small tool) it into several languages.  Then application reads file user specifies and automatically translate all text into that language.

To hold data in memory I've used vector, that hold user defined type, something like this:

class LanguageToken
UINT     m_nResourceId;
CString  m_csResourceString;

STL map or any other map can be used also, like it was mentioned before it is very convinient to associate resource id with resource text .

It works pretty well, we just have couple issues - like not all items in menus have ID.  So menu's have to translated by position, or contracted on a fly from string in the string table.  One other thing that all labels on all dialogs are placed with IDC_STATIC. ( or -1).  So you have to make sure that all labels you want to translate have to have own unique id.

Small probem with the way you want it implemented

IDC_BORED_ERROR     "you're too bored"

is that I don;t see the way how you going to find out wich control/text has IDC_BORED_ERROR associated with.  I couldn;t figure it out - so I resorted to storing it's numeric value.  That of cause forced me to parse resource.h file :-(.  

Of cause if all you want to do is just simplify translation process it is not an issue for you.

Hope it helps a little.
IainHereAuthor Commented:
Thanks jkr.

mblat - good info.  I've dropped some points off for you at 

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.