Что нового

AppTranslation Module - Добавление поддержки мультиязычности в вашу программу

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Вот пример добавления поддержки мультиязычности в вашу программу:

Код:
#include <GUIConstantsEx.au3>

Global Const Enum _
	$iMsg_First = 0, _
		$iMsg_Title, $iMsg_Label1, $iMsg_Button1, _
		$iMsg_CheckBox1, $iMsg_CheckBox2, $iMsg_CheckBox3, $iMsg_CheckBox4, $iMsg_CheckBox5, $iMsg_CheckBox6, $iMsg_CheckBox7, _
	$iMsg_Last

Global $aMessage = _AppTranslation_Proc(@ScriptDir & "\Russian.lng")

GUICreate($aMessage[$iMsg_Title], 300, 300)

GUICtrlCreateLabel($aMessage[$iMsg_Label1], 20, 10)
GUICtrlCreateButton($aMessage[$iMsg_Button1], 20, 40)

$iTop = 100

For $i = 1 To 7
	GUICtrlCreateCheckbox($aMessage[Eval("iMsg_CheckBox" & $i)], 20, $iTop)
	$iTop += 20
Next

GUISetState()

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func _AppTranslation_Proc($sLangFile)
	Local $aMessage[$iMsg_Last+1], $sMessage
	
	;Default values
	$aMessage[$iMsg_Title] = "My App"
	$aMessage[$iMsg_Label1] = "This is the label text"
	$aMessage[$iMsg_Button1] = "Press me"
	$aMessage[$iMsg_CheckBox1] = "CheckBox number... 1"
	$aMessage[$iMsg_CheckBox2] = "CheckBox number... 2"
	$aMessage[$iMsg_CheckBox3] = "CheckBox number... 3"
	$aMessage[$iMsg_CheckBox4] = "CheckBox number... 4"
	$aMessage[$iMsg_CheckBox5] = "CheckBox number... 5"
	$aMessage[$iMsg_CheckBox6] = "CheckBox number... 6"
	$aMessage[$iMsg_CheckBox7] = "CheckBox number... 7"
	
	If Not FileExists($sLangFile) Then
		Return $aMessage
	EndIf
	
	For $i = $iMsg_First + 1 To $iMsg_Last - 1
		$sMessage = IniRead($sLangFile, "Translation", "0" & $i, "")
		$sMessage = BinaryToString(StringToBinary($sMessage), 4)
		
		If $sMessage <> "" Then
			$aMessage[$i] = $sMessage
		EndIf
	Next
	
	Return $aMessage
EndFunc


Содержание языкового файла (Russian.lng):
INI:
[Translation]
01="Заголовок моей программы"
02="Это текст надписи"
03="Нажмите на меня"
04="Опция номер... 1"
05="Опция номер... 2"
06="Опция номер... 3"
07="Опция номер... 4"
08="Опция номер... 5"
09="Опция номер... 6"
010="Опция номер... 7"

файл должен быть сохранён в кодировке UTF-8, иначе записи будут плохо отображаться.

P.S
В своих программах я использую более сложную форму данной концепции, но этот пример только для общего представления.
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Вот так было бы удобнее разбираться в коде, если бы lang-файл выглядил так:
[Translation]
MAIN_TITLE = Заголовок моей программы
LABEL_TEXT = Это текст надписи
PRESS_ON_ME = Нажмите на меня
OPTION_1 = Опция номер... 1
OPTION_2 = Опция номер... 2
OPTION_3 = Опция номер... 3
OPTION_4 = Опция номер... 4
OPTION_5 = Опция номер... 5
OPTION_6 = Опция номер... 6
OPTION_N = Опция номер... 7
И в примере можно было бы добавить Combo, в котором можно выбрать язык. При выборе в Combo автоматически менять язык всех контролов.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
kzru_hunter [?]
Вот так было бы удобнее разбираться в коде
Ничего удобного здесь не вижу, придётся для каждого элемента читать по уникальному ключу.


ожно было бы добавить Combo, в котором можно выбрать язык
Я же написал, как раз для таких замечании:
[?]
P.S
В своих программах я использую более сложную форму данной концепции, но этот пример только для общего представления.
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
CreatoR [?]
Ничего удобного здесь не вижу, придётся для каждого элемента читать по уникальному ключу.
Можно всю секцию целиком прочитать, и потом уже думать, как работать с массивом, который возвратила функция IniReadSection в плане оптимизации временных затрат.

Текст кода может быть очень большим, и разбирать в каждой такой строке
Код:
GUICtrlCreateLabel($aMessage[2], 20, 10)

значение в массиве $aMessage[N] будет не удобно. Придётся каждый раз переключаться на lang-файл, чтобы понять, какой текст записан в этот массив.
Особенно будет не удобно, если открыть свой старый проект с поддержкой мультиязычности, например, через год.
Пример lang-файла, который я предложил, как раз имеет такой же вид, как и в Counter-Strike 1.6 при написании плагинов.

Могу предложить свой вариант добавления поддержки мультиязычности, если никто не будет против :smile:
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
kzru_hunter [?]
Текст кода может быть очень большим, и разбирать в каждой такой строке
...
значение в массиве $aMessage[N] будет не удобно
Можно присвоить константы для этого:

Код:
#include <GUIConstantsEx.au3>

Global Const Enum _
	$iMsg_First = 0, _
		$iMsg_Title, $iMsg_Label1, $iMsg_Button1, _
		$iMsg_CheckBox1, $iMsg_CheckBox2, $iMsg_CheckBox3, $iMsg_CheckBox4, $iMsg_CheckBox5, $iMsg_CheckBox6, $iMsg_CheckBox7, _
	$iMsg_Last

Global $aMessage = _AppTranslation_Proc(@ScriptDir & "\Russian.lng")

GUICreate($aMessage[$iMsg_Title], 300, 300)

GUICtrlCreateLabel($aMessage[$iMsg_Label1], 20, 10)
GUICtrlCreateButton($aMessage[$iMsg_Button1], 20, 40)

$iTop = 100

For $i = 1 To 7
	GUICtrlCreateCheckbox($aMessage[Eval("iMsg_CheckBox" & $i)], 20, $iTop)
	$iTop += 20
Next

GUISetState()

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func _AppTranslation_Proc($sLangFile)
	Local $aMessage[$iMsg_Last+1], $sMessage
	
	;Default values
	$aMessage[$iMsg_Title] = "My App"
	$aMessage[$iMsg_Label1] = "This is the label text"
	$aMessage[$iMsg_Button1] = "Press me"
	$aMessage[$iMsg_CheckBox1] = "CheckBox number... 1"
	$aMessage[$iMsg_CheckBox2] = "CheckBox number... 2"
	$aMessage[$iMsg_CheckBox3] = "CheckBox number... 3"
	$aMessage[$iMsg_CheckBox4] = "CheckBox number... 4"
	$aMessage[$iMsg_CheckBox5] = "CheckBox number... 5"
	$aMessage[$iMsg_CheckBox6] = "CheckBox number... 6"
	$aMessage[$iMsg_CheckBox7] = "CheckBox number... 7"
	
	If Not FileExists($sLangFile) Then
		Return $aMessage
	EndIf
	
	For $i = $iMsg_First + 1 To $iMsg_Last - 1
		$sMessage = IniRead($sLangFile, "Translation", "0" & $i, "")
		$sMessage = BinaryToString(StringToBinary($sMessage), 4)
		
		If $sMessage <> "" Then
			$aMessage[$i] = $sMessage
		EndIf
	Next
	
	Return $aMessage
EndFunc
 

kzru_hunter

Осваивающий
Сообщения
144
Репутация
49
Добавлять новые переменные для новых контролов не удобно.
Удобнее смотрелось бы вот так:
Код:
__SetLanguage("Russian.lng")
...
GUICtrlCreateLabel(__GetLangText("MAIN_TITLE"), 20, 10)
...
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
kzru_hunter [?]
Удобнее смотрелось бы вот так
Удобство понятие относительное, тем более что в такой форме инициализация скрипта будет задерживаться дольше обычного.
 
Верх