Поддержка многоязычности

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik

Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Не буду ни с кем спорить, что лучше, а что хуже - у каждого свое IMHO, и каждый в чем-то прав. Выскажу только свои соображения по этому поводу...
В свое время (когда был полным бараном в программировании) каких только компонентов я не перепробовал :). Чуток "поумневши" начал их (компоненты) "ковырять"... И был поражен (не во всех случаях, но в большинстве) "корявости" их работы.
Ну и как настоящий СНГ-овский программер начал сам "изобретать велосипед".
Пришел к выводу, что гибче (и при разработке, и при использовании - юзер сам может добавлять-изменять свою локализацию) формат текстового файла. Вариантов несколько -
1.TStringList - загрузил раз и "тянешь" оттель.
2.TIniFile - практически то-же, что и первый вариант (см. исходники TIniFile).
Ну а как быть, если программа на API и добавление любого из вышеуказанных классов неоправдвнно "раздует" размер?
Тут 3-й вариант
GetPrivateProfileString - работает аж со свистом... Даже на "медленных" машинах.
А подразобравшись с PrivateProfileString я вообще отказался в своих программах от TIniFile. И не жалею - работает быстрее.

Еще один момент. В качестве ключа я использую не название или Caption по дефолту компонента, а его Tag. Очень удобно, т.к. этот-же Tag используется в качестве идентификатора команды. Т.е. не на каждую кнопку-меню-и т.д. по событию OnClick, а одно OnClick на группу и дальше через case выполнение команды. Таким образом можно идентифицировать и сообщения, и внутренние команды и т.д. и т.п.

З.Ы. Кому такой подход не нравится, просьба свое "Фа" в мой адрес оставить при себе :) и прочитать первые строки этого поста :).
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение Nik »

SCHMaster
А подразобравшись с PrivateProfileString я вообще отказался в своих программах от TIniFile. И не жалею - работает быстрее.
Аналогично :) В свое время нашел этот способ в исходниках InnoSetup и приспособил под свои нужны. Очень удобно (и не только для локализации)...
Аватара пользователя
SCHMaster
Сообщения: 296
Зарегистрирован: Ср дек 15, 2004 02:32
Откуда: Киев
Контактная информация:

Сообщение SCHMaster »

Nik
Совершенно верно, зачем в очередной раз изобретать велосипед (хотя не спорю, некоторые приимущества в TIniFile есть), когда можно с успехом пользоваться "колесами" самой системы.
Аватара пользователя
Моторокер
Сообщения: 1517
Зарегистрирован: Пт май 06, 2005 08:22
Откуда: г. Пермь (читается Перьмь)
Контактная информация:

Сообщение Моторокер »

это же всё в цикле делается

Ничево подобного!
Почему нет? Немного можно автоматизировать. Количество проверок будет cтолько же, сколько на форме будет компонентов разных типов. Можно также сделать цикл по формам.

Код: Выделить всё

  for i:= 0 to ComponentCount-1 do begin
    if Components[i] is TButton then
      (Components[i] as TButton).Caption:= ini.ReadString(Form1.Name, (Components[i] as TButton).Name, (Components[i] as TButton).Caption);
  end; 
ini файл

Код: Выделить всё

[Form1]
Button1=Текст 1
Button2=Текст 2
Button3=Текст 3
Как вариант для большей наглядности ini файла:

Код: Выделить всё

  for i:= 0 to ComponentCount-1 do begin
    if Components[i] is TButton then
      (Components[i] as TButton).Caption:= ini.ReadString(Form1.Name, (Components[i] as TButton).Name + '.Caption', (Components[i] as TButton).Caption);
  end; 
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение Nik »

Моторокер
Имхо, это не оптимально. В моем случае, например, локализуется лишь 10% компонентов формы. А такой вот алгоритм будут "бегать" по всем. Смысл?
Аватара пользователя
Моторокер
Сообщения: 1517
Зарегистрирован: Пт май 06, 2005 08:22
Откуда: г. Пермь (читается Перьмь)
Контактная информация:

Сообщение Моторокер »

10% – это 10 компонентов или больше?
Понятно, что если переводить много не нужно, то можно и перечислить все компоненты по порядку. Читать переводы можно даже не используя ini файлы, просто читать ReadLn из TextFile.
Но так ли уж долго выполняется данный цикл?

Смысл в том, что алгоритм универсальный, точно так же можно выгружать ini файлы для перевода. А там уже неважно, какие компоненты куда положены, добавлены, ini файл всегда актуален.

Есть ещё правда константы, но их тоже можно занести в какой-нибудь массив и читать тоже в цикле.
плагины для Total Commander, статьи Graphics Converter; NSCopy; SEO HTML; KillOK; Плагин на Delphi
ПармаСруб - строительство домов и бань в Перми
Аватара пользователя
Моторокер
Сообщения: 1517
Зарегистрирован: Пт май 06, 2005 08:22
Откуда: г. Пермь (читается Перьмь)
Контактная информация:

Сообщение Моторокер »

Можно ещё избавиться от
if Components is TButton TControl then
напрямую присваивать
try
(Components as TButton TControl).Hint:= 'ля-ля-ля';
except
end;
Последний раз редактировалось Моторокер Ср июл 12, 2006 13:06, всего редактировалось 1 раз.
vserd
Сообщения: 118
Зарегистрирован: Вт апр 26, 2005 16:54

Сообщение vserd »

Моторокер
Можно ещё избавиться от
if Components is TButton then [\quote]
можно но не нужно. Не факт что компонент всегда будет иметь свойство которое имеет TButton. В данном случае Hint.
Всякая оптимизация должна иметь свои границы.
Аватара пользователя
Моторокер
Сообщения: 1517
Зарегистрирован: Пт май 06, 2005 08:22
Откуда: г. Пермь (читается Перьмь)
Контактная информация:

Сообщение Моторокер »

Не факт что компонент всегда будет иметь свойство которое имеет TButton.
Ошибочка. Исправил. Посмотрел код – там так:
try
(Components as TControl).Hint:= S;
except
end;


Прокатит только для хинтов, Caption придется всё-таки проверять на is для каждого вида контролов.
Так переделываю обычные хинты в многострочные.
Если не факт, срабатывает try..except.

Взбрело в голову – да так можно и координаты контролов менять. Допустим, надпись не помещается, сменил Width или Left в ini файле и всё путём.
Ответить