Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Single Binary for localized applications

Status
Not open for further replies.

gurdeep291

Programmer
Jul 1, 2003
1
IN
Is there a way to achieve a single binary for all languages. I am currently looking at Multilizer which produces a single binary. However the binary file is not suitable as it does not automatically aligns the layout of the controls to adjust to the new String lengths.
 
Theres a couple of things that one would have to do when playing with different spoken languages. I'm assuming that you're actually coding this application with source and all that.

You have no choice but to concern yourself with the lengths of different phrases for each language. You also have to deal with LEFT TO RIGHT languages and RIGHT TO LEFT lanaguages, but thats a whole different story. Lets just stick with left-to-right languages. If you want to make certain that everything looks `professional` regardless of language, you would need to figure out how to get each component to be aware of their position and tell other components to move their butts over. Think of it kind of like a parent/child relationship.

One way of doing it is make a custom label and make a new property for it. This property would be a tList containing pointers to objects that have to be aware of any changes to this labels text change. You could override the Caption property of the new label component, so that when its caption is changed, the new caption property will go through the tList and update the child component positions accordingly after its figured out how many pixels wide the new text is going to be.

Personally, I would not put the language text within the executable file. I would use something like SQLite and put your languages in a database. Two reasons. First, not a lot of people know how to work with SQLite tables from a command prompt there by making your language files somewhat secure and tamper-proof. IMHO, SQL is VERY powerful and well worth learning. The second reason is that it can get extremely messy if you decide to use a single file, or an ini file, or anything else that can be opened up with ease using NOTEPAD. Beleive it or not, theres people out there that think they know it all, and tend to show how much they know when they break things and not know how to put it back together. ;)

The major reason that I would put the language into a database is that when you insert a word, or a phrase into the database, you can reference by ID or by your preferred language as an identifier.

An example of some tables:

Code:
tblComponent
  ID:integer
  YourDesc:varchar(255)

tblEnglish
  fkID:integer;
  ComponentText:varchar(255);

tblFrench
  fkID:integer;
  ComponentText:varchar(255);

This would allow you to validate the language DB in two ways.

1> You can validate that each language table has a reference to what the original language is. Meaning that Nom: is in the french table with a reference to Name: in the tblComponents table.
2> If, by chance, a reference doesn't exist, code in a safeties to use YourDesc so your UI doesn't turn up blanks.

For an example, if using a label, you can use the labels TAG property (Which is an integer) to identify what phrase is supposed to go as its caption.

Code:
SelectedLanguage:='English';
LabelID:=Label1.tag;
SQLStr:='select ComponentText from tbl'+SelectedLanguage+' where fkID='+inttostr(LabelID);
SQLRecordSet.commandtext:=SQLStr;
SQLRecordSet.execute;
if not SqlRecordSet.EOF then
  Label1.Caption:=SQLRecordSet.Fields.Field[0].asString;
end if;

Or instead of using label IDs, you can do searches based on phrases of whats in the labels caption like so (With less checking of validity):
Code:
SearchText:=QuotedStr(Label1.caption);
TableToLookup:='tblfrench';
SQLStr:='select ComponentText from '+TableToLookup+' where fkID=(select ID from tblcomponents where YourDesc='+SearchText+') limit 1';
SQLDataSet.commandtext:=SQLStr;
SQLDataSet.execute;
Label.Caption:=SQLDataSet.Feilds.FieldByName('ComponentText').AsString;

This probably is the better way, that way you can design the forms the way you want to, using the language you want to. During the creation of the label at run time, you can check to see if the database has that phrase already. If not, automatically add it to the tblComponents table. You can also put in a check so that this isn't done on a customers machine, as it most certainly will slow things down, depending on the number of components you're translating. There by the next idea for validity.

The other reason I would push for dumping the language to a database is that you can write another small application, that runs a single SQL statment against each table to make sure that the language table has something for that component.
Code:
select * from tblComponent where ID not in (select fkID ID from tblFrench)
{Or something like that}

The results could come back looking like this:

Code:
The french table doesn't have the proper phrase for:
  [1] Name:
  [2] Password:
  [10] The answer is Fourty-Two.

There is a lot more complexity to this method, yeah, I agree, but the benefit of this is that if you decide to add another language, you don't have to redistribute the ENTIRE application again. Just make that single language data file available for download somewhere on the net. Have your program download it via whatever means you want, place that file where it needs it, then re-open the language database and voila, new language in place, and ZERO user intervention. The bonus with the DB method is that if there is another language added, and the lengths of the new phrases are longer than anything that already exists for a particular label, the software will already know how to deal with the new length and adjust appropriately.

The other thing you could do, which might be a bit less tedious (And more uncool) is just make sure you leave enough white space for the text thats going into the components. Doesn't make things look good, especially when an english word is 3 characters long, and the french equivilant turns out to be 20.

{smirk} All that is what I would tell others to do. Myself... I just say "English only". ;)

*Note that all this code is untested*


-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=
NEVER send the boss to do a techs job
 
There's an old expression that says "When the only tool in your toolbox is a hammer, everything starts looking like a nail."

I don't think I'd make every mult-language app I wrote require a database interface, just to do the job on a String Resource file, but that's just me...

For an excellent example of what I'm talking about, download and look at project ZipMasters (with delphi source). My version supports 22 languages and is not the latest.

Xavier Mor-Mur even has a seperate utility to translate TZip resource files here:

Roo
Delphi Rules!
 
Roo;

String Resources are a great tool as well. Myself, I tend to like reinventing the wheel for the simple reason that one learns a lot more from that. I'm a nuts and bolts kind of guy, and I want to know how everything works. My experience also does not include writing for multiple languages, so string resources aren't something that would pop into my head first thing. Databases are my favorite tool and I've gotten quite adept to using them effectively for nearly everything other than making a cup of coffee. ;)


-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=
NEVER send the boss to do a techs job
 
I code for profit. I use efficiency to obtain that goal. And only post to threads where I do have "experience".
smiletiniest.gif
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top