WINAMP.COM | Forums > Developer Center > NSIS Discussion > Language strings: Include them or add them as resources? |
Last Thread
Next Thread
|
| Author |
|
|
CancerFace Senior Member
Registered: Apr 2006 |
Recently I decided to add support for multiple languages to some NSIS tool that I have been developing, after I was asked if the end user could use some sort of resource editing tool to modify my program in such a way that localization in their language would be achieved. However if someone wanted to add some new language they would have to obtain the source code and recompile the program after adding the string in their language.code: So the question that I was faced with was how can I add support for another language if I do not want to have the default language(s) present, without changing the source code? I don't like the idea of having external language files and since I was playing around with Message Table resources in DLLs recently I thought that I could give it a shot and try to add my own messages to my program in the form of Message Table resources. In this way the end user can choose to use something like Resource Hacker to change the language of the resource and modify all the strings on that table, thus achieving localization for their system. Furthermore I can use two tables inside the message table resource, one using {LANG_NEUTRAL,SUBLANG_NEUTRAL} and the other using some other language (for example english). The end user can change the table that contains the language (1033 for example) but leave the neutral language table unaltered, so that if the program is executed on a system that does not contain the end user's language, the neutral language would be picked instead. To achieve the above I used a tool called XN Resource Editor to add a new message table resource to an already compiled version of my program. After saving the modified program I used Resource Hacker to edit the message table(s) and exported them as RES files. These files are binary and not easy to edit, but once they are imported to an EXE file they can be easily manipulated using Resource Hacker. So now I had the message tables in an RES format and I wanted to add them to my program upon compiling it. I used the following batch script during compilation (header.cmd): This batch file was called from my NSIS script during compilation time:code: The resulting program contained the message table(s) and it was easy to generate a macro that would pick the strings from those tables depending on the system language:code: Using the macro is also straight forward:code: code: Everything looked sweet, until I tried to emulate the end user's behavior ... I tried to edit the strings on the message tables using resource Hacker on the final program and failed miserably: the program fails to run after any string has been tampered with! I managed to get around this problem by adding to my NSIS script. Not ideal but at least it works.code: Although I am quite happy with the result, I am not sure if this is the best approach to the problem described at the beginning of this post. I am certainly not happy having to disable the CRC check. I would appreciate any comments/suggestions/thoughts. CF Last edited by CancerFace on 06-02-2006 at 03:10 PM |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
Very nice __________________ |
||
|
|
|
CancerFace Senior Member
Registered: Apr 2006 |
Added a WIKI page code: I also forgot to include the definitions for the FormatMessage API call: code: CF |
||
|
|
|
Afrow UK Moderator
Registered: Nov 2002 |
I'm not sure how important it is, but I've read that the System plugin works faster if you use /NOUNLOAD... __________________ |
||
|
|
|
CancerFace Senior Member
Registered: Apr 2006 |
To be honest I could not see any difference with and without the /NOUNLOAD switch Calling the function is easy:code: code: CF [Edit] Right ... I am getting a handle on the EXE itself then I am using the System::Free call ... This was the cause of the unpredicted crashes so ignore it. Better yet, get a handle on the running process at .onInit, place it on some variable and then use the already open handle instead of getting a new handle every time ... I updated the code of this post to reflect these changes CF Last edited by CancerFace on 06-05-2006 at 10:27 AM |
||
|
|
|
CancerFace Senior Member
Registered: Apr 2006 |
I played a bit more with this and it seems that both the macro and the function that I posted don't work too well when the banner blugin is in use. I managed to get them both operational though by using the FreeLibrary API call: code: code: As for the size of the installer, I should mention that for the message tables that I added (57 entries each), there was an increase in terms of size of about 4kb per table, as opposed to 0kb when using a header file. ![]() CF |
||
|
|
|
CancerFace Senior Member
Registered: Apr 2006 |
Just a heads-up on the above: I noticed that using this method for displaying messages fails if it is coupled with the banner plugin. It seems that the banner plugin is also getting a handle to the installer and attaches the banner as a thread to the main module, if I read the code correctly. Even if I try to get a handle using GetModuleHandleExA in XP, using the pin flag (so that FreeLibrary will not destroy the handle), every time there is a change on the banner I get a GPF. In windows 2000 DrWatson was kind enough to inform me that the error is due to an access violation of GetModuleHandleW. I changed the macro/function so that they would call the ANSI version of the above function, but the error remained, and DrWatson reported an access violation on GetModuleHandleW again (?). But is it the banner plugin to blame? I think not ... code: as it shows both dialog boxes, while this code works: and it shows only the second dialog box.code: I am getting the same effect if I use a function instead of a macro. Any ideas? CF |
||
|
|
|
kichik M.I.A. [NSIS Dev, Mod]
Registered: Oct 2001 |
GetModuleHandleA is just a wrapper for GetModuleHandleW. That's why GetModuleHandleW is always called eventually. __________________ |
||
|
|
|
ginglese Junior Member
Registered: Jul 2006 |
hi all, |
||
|
|
|
kichik M.I.A. [NSIS Dev, Mod]
Registered: Oct 2001 |
LANGID is a number. It can represented as hexadecimal or decimal. $LANGUAGE contains a number which is the LANGID for the current language. With the system plug-in, you can use `a` instead of `$LANGUAGE`. __________________ |
||
|
|
|
ginglese Junior Member
Registered: Jul 2006 |
no sure to understand |
||
|
|
|
kichik M.I.A. [NSIS Dev, Mod]
Registered: Oct 2001 |
Instead of passing $LANGUAGE, you can simply pass `a`. code: __________________ |
||
|
|
|
ginglese Junior Member
Registered: Jul 2006 |
|
||
|
|
|
Last Thread Next Thread
|
WINAMP.COM | Forums > Developer Center > NSIS Discussion > Language strings: Include them or add them as resources? |
Forum Rules:
|