Archive: Very advanced internationalisation


Very advanced internationalisation
There is a program in english with different language packages for other languages and three InstTypes:

InstType $(inst_minimal)  #means installation without any additional language --> only english
InstType $(inst_standard) #means installation with the language chosen at installatin begining as additional packet
InstType $(inst_full) #means installation with all available language packets

This is what I want to do:
[list=1][*]make the installer available in multilangue (done by MUI_RESERVEFILE_LANGDLL and MUI_LANGUAGE)[*]make the license file available in more than on language (done by MUI_PAGE_CUSTOMFUNCTION_SHOW and language strings containing the filename)[*]take the choosen language from the installer, and precheck it (done by MUI_PAGE_CUSTOMFUNCTION_SHOW and "!insertmacro SelectSection ${SEC0001}")[*]take the choosen language from the installer, put the language file in InstType "standard" (how to say which group schould be added by SF_SECGRP ???)[*]delete the non-use InstType when the language is english (Is it possible to 'delete' an InstType at runtime [$(inst_minimal) or $(inst_standard)] if the user chooses english, I tried CB_DELETESTRING but it seems that the wrong string is deleted?)[/list=1]

I use the following code (with InstTypes as shown before )


...
!define LIC_NAME $(lic_filename)
...

# Installer pages
!insertmacro MUI_PAGE_WELCOME
!define MUI_PAGE_CUSTOMFUNCTION_SHOW addLicense
!insertmacro MUI_PAGE_LICENSE ..\bin\Release\lizenz.rtf # some file has to stand here, the right language file is choosen dynamically
!define MUI_PAGE_CUSTOMFUNCTION_SHOW MySpecialLanguageThings
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILESES

# Installer languages
!insertmacro MUI_LANGUAGE German
!insertmacro MUI_LANGUAGE English
!insertmacro MUI_LANGUAGE French

...


Function addLicense
# addLicence shows the right licence file instead allowing only one via MUI_PAGE_LICENSE

ClearErrors
System::Call 'kernel32::CreateFile(t "$EXEDIR\${LIC_NAME}", i ${GENERIC_READ}, i ${FILE_SHARE_READ}, i 0, i ${OPEN_EXISTING}, i 0, i 0) i .r0'
IfErrors exit
System::Call 'kernel32::GetFileSize(i r0, i 0) i .r1'
IntOp $1 $1 + 1 ; for terminating zero
System::Alloc $1
Pop $2
System::Call 'kernel32::ReadFile(i r0, i r2, i r1, *i .r3, i 0)'
System::Call 'kernel32::CloseHandle(i r0)'
FindWindow $0 "#32770" "" $HWNDPARENT
GetDlgItem $0 $0 1000
SendMessage $0 ${WM_SETTEXT} $0 $2
System::Free $2
exit:
FunctionEnd

...
# Installer sections
Section $(SEC0000_NAME) SEC0000
SetOutPath $INSTDIR
SetOverwrite on
File ..\bin\Release\license.rtf
SetOutPath $INSTDIR\en
File /r ..\bin\Release\help\en\*
WriteRegStr HKLM "${REGKEY}\Components" MainProg 1
SectionIn RO # This Section is allways checked and cannot be disabled
SectionEnd

SectionGroup /e $(SECGRP0000_NAME) SECGRP0000
# what languages belongs to standard type
# is choosen dynamically via MyOnGuiInit
Section /o $(SEC0001_NAME) SEC0001
SetOutPath $INSTDIR\de
SetOverwrite on
File /r ..\bin\Release\de\*
File /r ..\bin\Release\help\de\*
File ..\bin\Release\lizenz.rtf
WriteRegStr HKLM "${REGKEY}\Components" German 1
SectionIn 3
SectionEnd

Section /o $(SEC0002_NAME) SEC0002
SetOutPath $INSTDIR\fr
SetOverwrite on
File /r ..\bin\Release\fr\*
File /r ..\bin\Release\help\fr\*
WriteRegStr HKLM "${REGKEY}\Components" French 1
SectionIn 3
SectionEnd
SectionGroupEnd


Function MySpecialLanguageThings
# delete not used InstType if language is English
# does not work... deletes the wrong string - no custom anymore
${If} $(SEC0000_NAME) == "Main Program"
Push $R0
FindWindow $R0 "#32770" "" $HWNDPARENT
GetDlgItem $R0 $R0 1017
SendMessage $R0 ${CB_DELETESTRING} 3 $(inst_standard)
Pop $R0
${Else}
# selecting installer sections (languages)
# adding to a group does not work in this way...
${If} $(SEC0001_NAME) == "Deutsch"
!insertmacro SetSectionFlag ${SEC0001} SF_SECGRP
!insertmacro SelectSection ${SEC0001}
${Else}
${If} $(SEC0002_NAME) == "Français"
!insertmacro SetSectionFlag ${SEC0002} SF_SECGRP
!insertmacro SelectSection ${SEC0002}
${EndIf}
${EndIf}
${EndIf}
FunctionEnd

LangString SEC0000_NAME ${LANG_ENGLISH} "Main Program"
LangString SEC0000_NAME ${LANG_GERMAN} "Hauptprogramm"
LangString SEC0000_NAME ${LANG_FRENCH} "Programme"
LangString SEC0001_NAME ${LANG_ENGLISH} "German"
LangString SEC0002_NAME ${LANG_ENGLISH} "French"
LangString SEC0001_NAME ${LANG_GERMAN} "Deutsch"
LangString SEC0002_NAME ${LANG_FRENCH} "Français"
LangString lic_filename ${LANG_ENGLISH} "..\bin\Release\license.rtf"
LangString lic_filename ${LANG_GERMAN} "..\bin\Release\lizenz.rtf"
# no licence file for French yet --> we take the english one
LangString lic_filename ${LANG_FRENCH} "..\bin\Release\license.rtf"


Maybe there is a more elegant way than comparing with self defined strings (that maybe change later)?

${If} $(SEC0002_NAME) == "Français"
...
LangString SEC0002_NAME ${LANG_FRENCH} "Français"

Originally posted by Afrow UK
[...]{SF_SECGRP} [...] setting it means you are turning your section into a group marker.
How can I add/remove a section to/from a group at runtime?

To "delete" installation types, you can use InstTypeSetText with an empty string. You can then use SectionSetInstTypes to set the installation type to which each section belongs. To hide sections, set their text to an empty string using SectionSetText.


SectionSetInstTypes worked fine, 'but InstTypeSetText 1 ""' doesn't seem to work: the second InstType is still there.

Function MySpecialLanguageThings
# delete not used InstType if language is English
# by setting the text of standard (sectinos are counted from 0)
# to an empty string
${If} $(SEC0000_NAME) == "Main Program"
InstTypeSetText 1 ""
${Else}
# selecting installer sections (languages)
# set a group needs binary bit b110 = d6.
${If} $(SEC0001_NAME) == "Deutsch"
SectionSetInstTypes ${SEC0001} 6
!insertmacro SelectSection ${SEC0001}
${Else}
${If} $(SEC0002_NAME) == "Français"
SectionSetInstTypes ${SEC0002} 6
!insertmacro SelectSection ${SEC0002}
${EndIf}
${EndIf}
${EndIf}
FunctionEnd


Any idea how to ask for the choosen language other than comparing with the manaully defined LangStrings?

InstTypeSetText is zero based. Make sure you got the numbers right.

$LANGUAGE will give you the language identifier which can be compared to ${LANG_*}.


$LANGUAGE gives the choosen LCID, therefore
1031 for German
1033 for English
1036 for French

if this will be ALWAYS like that it's OK, even if "readable" synonyms (like German, English, French) would be better.

using
InstTypeSetText 1 ""
there are still all InstTypes there. Any more ideas about this?


$LANGUAGE gives chosen language identifier (LANGID). It can be compared to ${LANG_GERMAN}, ${LANG_ENGLISH}, ${LANG_FRENCH} and friends which contain the appropriate language identifier.

Using InstTypeSetText with an empty string works fine for me. You'll have to be a bit more specific on your usage.


I have the solution now. The problem was, that I used my Function here:

!define MUI_PAGE_CUSTOMFUNCTION_SHOW MySpecialLanguageThings
!insertmacro MUI_PAGE_COMPONENTS


But seem to has to be used here:


!define MUI_CUSTOMFUNCTION_GUIINIT MySpecialLanguageThings


PS: ${If} $LANGUAGE == ${LANG_ENGLISH} works fine!


I had problems with the multi language license file in Vista and tried to find a better soulution. This is the native way to do this (Solution at sourceforge/bug-tracker):

...

# Reserved Files
!insertmacro MUI_RESERVEFILE_LANGDLL

...

# Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE $(lic_filename)
!insertmacro MUI_PAGE_COMPONENTS
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuGroup
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

# Installer languages
!insertmacro MUI_LANGUAGE German
!insertmacro MUI_LANGUAGE English
!insertmacro MUI_LANGUAGE French

...

LicenseLangString lic_filename ${LANG_ENGLISH} "..\bin\Release\license.rtf"
LicenseLangString lic_filename ${LANG_GERMAN} "..\bin\Release\lizenz.rtf"
# no licence file for French yet --> we take the english one
LicenseLangString lic_filename ${LANG_FRENCH} "..\bin\Release\license.rtf"

Hey this works perfect! put this on the wiki it can be helpful for others too...
Thanks so far.


IMHO, synonyms are not better in that spot..

You wrote:
"SNIP ... even if "readable" synonyms (like German, English, French) would be better. SNAP"

because: Then you can not calculate base and sublanguages, see the article:

http://nsis.sourceforge.net/MoreInfo...about_LCID.27s