Клубове Дир.бг
powered by diri.bg
търси в Клубове diri.bg Разширено търсене

Вход
Име
Парола

Клубове
Dir.bg
Взаимопомощ
Горещи теми
Компютри и Интернет
Контакти
Култура и изкуство
Мнения
Наука
Политика, Свят
Спорт
Техника
Градове
Религия и мистика
Фен клубове
Хоби, Развлечения
Общества
Я, архивите са живи
Клубове Дирене Регистрация Кой е тук Въпроси Списък Купувам / Продавам 22:08 03.06.24 
Компютри и Интернет
   >> Delphi
Всички теми Следваща тема *Кратък преглед

Тема Многоезичен интерфейс  
Автор tolini (непознат )
Публикувано19.03.07 16:08



Прегледах отговорите по темата и най-подходящото решение за мен би бил вариянта с *.INI - файл. Разгледах няколко такива и по отношение на създаването на такъв файл смятам, че всичко ми е ясно. Проблема ми е по отношение на програмната част, тоест, как да направя връзката с такъв файл от приложната програма на Delphi. Ще се радвам ако някой ми помогне с някой прост пример.



Тема Re: Многоезичен интерфейснови [re: tolini]  
Автор vido (новак)
Публикувано19.03.07 18:27



Най- добра информация по темата ще намериш в делфи хелпа.
Напиши TIniFile и натисни F1.



Тема Re: Многоезичен интерфейснови [re: tolini]  
Автор andrew_nikoloff (bugbuster)
Публикувано19.03.07 22:09



По същество цялата задача се състои в това да си подмениш елементите на интерфейса, които са специфични за езика (надписи, картинки и други). Когато използваш INI файлове най-лесно ще е да имаш по един файл за всеки език. Изборът на език за интерфейса може да става или като потребителят избира един от файловете като го преименува, поставя в определена папка или нещо подобно, или пък в конфигурацията на програмата се задава от кой файл да си чете "преводите".
Съдържанието на INI файла може да ти бъде нещо от сорта на:
[Form1]
Buton1.Caption=Затваряне
Buton1.Hint=Изход от приложението
Label1.Caption=Изход от програмата
Picture1=BG_Logo.bmp
и т.н.
"Превеждането" на интерфейса на приложението в нашия случай може да стане така (по най-тривиалния начин):


procedure TForm1.FormShow(Sender: TObject);
begin
Button1.Caption := iniTranslations.ReadString('Form1', 'Button1.Caption', 'Изход');
Button1.Hint := iniTranslations.ReadString('Form1', 'Button1.Hint', 'Изход от програмата');
Label1.Caption := iniTranslations.ReadString('Form1', 'Label1.Caption', 'Изход');
Picture1.LoadFromFile(iniTranslations.ReadString('Form1', 'Picture1', 'BG_Logo.bmp'));
end;

С този пример само демонстрирам принципа на "превода". За реални приложения той е практически неприложим. Основните му недостатъци са, че при добавянето на компонент във формата програмистът трябва да се сети и да коригира кода за превод, а също така и размерът на кода за една по-сложна форма се получава бая голям и трудно ще се поддържа.
Един възможен изход от ситуацията е всяка форма да може да се превежда сама себе си. Ако имаш обща базова форма (форма, на която останалите да са ти наследници) можеш да си дефинираш един виртуален метод, който да обхожда всички контроли по формата и да ги "превежда". Ако нямаш общ родител - дефинирай си една процедурка някъде в някакво модулче, която да приема за параметър форма и да я превежда.
Обхождането на контролите на формата може да стане, като се ползват пропъртитата Controls и ControlCount. Проблемът обаче е, че ако имаш някакви контейнери (TPanel, TGroupBox, вложени форми и т.н.) техните контроли не влизат в този списък. Решението е ако при обхождането на списъка с контроли попаднем на наследник на TWinControl да обходим и неговите Controls (рекурсивно обхождаме всички контроли по формата). Ето една процедурка, която върши тая работа:

type
TtcCallBackMethod = procedure(Section: String; Control: TControl);

procedure TraverseControls(Section: String; Container: TWinControl; CallBackFunction: TtcCallBackMethod);
var
i: Integer;
Comp: TControl;
begin

for i := 0 to Container.ControlCount - 1 do
begin
Comp := Container.Controls[ i ]; //Все го забравям тоя таг... :-/
if (Comp is TWinControl) and (not (Comp is TCustomForm)) then
TraverseControls(Section, TWinControl(Comp), CallBackFunction);
CallBackFunction(Section, Comp);
end;
end;


Тази процедура ще обходи всичките ти контроли в подадената й форма и за всеки един от тях ще ти извика твоя метод, който си подал като параметър.
Той от своя страна трябва да провери какъв е този контрол и съответно да извлече неговите "преводи" от INI файла. Например:

procedure TranslateControl(Section: String; Control: TControl);
begin
if Control is TButton then
begin
(Control as TButton).Caption := iniTranslations.ReadString(Section, Control.Name + '.Caption', '');
(Control as TButton).Hint := iniTranslations.ReadString(Section, Control.Name + '.Hint', '');
end
else if Control is TImage then
begin
(Control as TImage).Picture.LoadFromFile(iniTranslations.ReadString(Section, Control.Name, ''));
end
else ...
...
...
...
end;

По този начин за да преведеш една форма трябва просто някъде от нея (например в OnShow събитието) да извикаш:

TraverseControls(Name, Self, TranslateControl);

По този код има какво да се подобри. Например в процедурата за "превеждане" на контрол можеш да правиш проверка дали в INI файла има такъв запис и ако го няма - да отбележиш това (например такава е ситуацията, когато в едно "преведено" вече приложение добавиш контрол в някоя форма. Например добавиш нов бутон).
Това решение също така не отчита някои други фактори на професионално направения многоезичен интерфейс. Например ширината на бутоните и т.н. Типичен пример - бутон "OK" на английски и "Потвърждение" на български. Познай дали в българската локализация текста ще се събере в бутона

Надявам се, че не съм те отегчил твърде много

Успех!

Редактирано от andrew_nikoloff на 19.03.07 22:14.



Тема Re: Многоезичен интерфейснови [re: andrew_nikoloff]  
Автор tolini (непознат )
Публикувано20.03.07 08:19



Благодаря ти за помощта. Ще пробвам по този начин.



Тема Re: Многоезичен интерфейснови [re: tolini]  
Автор backinblack (Ръси мозък)
Публикувано06.04.07 19:26



Не съм програмист и не знам как се реализира, но ако мога да помогна с идея как е реализирано в други програми.....
Доколкото схващам въпроса ти, съм срещал при "изучаването" на разни многоезични програми следното решение:

В инсталацията на програмата има папка Lаnguage и в нея има .txt файлове с имена Bulgarian, Iтаly, .......... със следното съдържание:

SECTION :Dictionary
----------------
Object :"Menu"
Key = "&File"
Value = "Файл"
{End Object : }
----------------
Object :"Menu"
Key = "&Open..."
Value = "Отвори..."
{End Object : }
----------------
Object :"Menu"
Key = "&Close"
Value = "Затвори"
{End Object : }
----------------
Object :"Menu"
Key = "&Import"
Value = "Импортиране"
{End Object : }
----------------
Object :"Menu"
Key = "&Save"
Value = "Запиши"
{End Object : }
----------------
Object :"Menu"
Key = "Save &As..."
Value = "Запиши като..."
{End Object : }
----------------
Object :"Menu"
Key = "E&xit"
Value = "Изход"
{End Object : }
----------------
Object :"Menu"
Key = "Recent File"
Value = "Последни файлове"
{End Object : }
----------------
Object :"Menu"
Key = "&Edit"
Value = "Редакция"

В настройката на програмата избираш езика, рестартираш и ок. Ако узера е малко по-грамотен и сам би могъл да си направи локализация.

В една друга програма, всички имена на антетки, бутони, съобщения за грешки и менюта бяха в аксески файл който се зарежда заедно със стартирането на програмата, като срещу всяко поле имаше възможност за записване в един друг език и езика в интерфейса се сменяше без рестарт на програмата.

Всички гениални неща са измислени от хора, които не са знаели, че са невъзможни.




Всички темиСледваща тема*Кратък преглед
Клуб :  


Clubs.dir.bg е форум за дискусии. Dir.bg не носи отговорност за съдържанието и достоверността на публикуваните в дискусиите материали.

Никаква част от съдържанието на тази страница не може да бъде репродуцирана, записвана или предавана под каквато и да е форма или по какъвто и да е повод без писменото съгласие на Dir.bg
За Забележки, коментари и предложения ползвайте формата за Обратна връзка | Мобилна версия | Потребителско споразумение
© 2006-2024 Dir.bg Всички права запазени.