Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];

Вниз

Сохранение заголовков всех компонентов формы   Найти похожие ветки 

 
__DATA__   (2006-02-22 08:30) [0]

Хочу сделать потдержку нескольких языков в программе, текущий язык сохраняю так :

procedure SaveDefaultLenguage(Form: TWinControl; FileName: String);
var
 i: Integer;
 ini: TINIFile;
begin
 try
   DeleteFile(FileName);
   INI := TINIFile.Create(FileName);
   for i := 0 to Form.ComponentCount-1 do
   begin
     if (Form.Components[i] is TLabel) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TLabel).Name,(Form.Components[i] as TLabel).Caption)
     else
     if (Form.Components[i] is TButton) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TButton).Name,(Form.Components[i] as TButton).Caption)
     else
     if (Form.Components[i] is TGroupBox) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TGroupBox).Name,(Form.Components[i] as TGroupBox).Caption)
     else
     if (Form.Components[i] is TCheckBox) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TCheckBox).Name,(Form.Components[i] as TCheckBox).Caption)
     //bsSkin ext
     else
     if (Form.Components[i] is TMenuItem) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TMenuItem).Name,(Form.Components[i] as TMenuItem).Caption)
     else
     if (Form.Components[i] is TbsSkinCheckRadioBox) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TbsSkinCheckRadioBox).Name,(Form.Components[i] as TbsSkinCheckRadioBox).Caption)
     else
     if (Form.Components[i] is TbsSkinSpeedButton) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TbsSkinSpeedButton).Name,(Form.Components[i] as TbsSkinSpeedButton).Caption)
     else
     if (Form.Components[i] is TbsSkinStdLabel) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TbsSkinStdLabel).Name,(Form.Components[i] as TbsSkinStdLabel).Caption)
     else
     if (Form.Components[i] is TbsSkinButton) then
       ini.WriteString("COMPONENTS",(Form.Components[i] as TbsSkinButton).Name,(Form.Components[i] as TbsSkinButton).Caption)
   end;
 finally
   INI.Free;
 end;
end;


Но при попытки записи заголовка определенного элемента в ini файл выскакивает Access Violation. Код вроде правильный и AV вылетать не должен, что я упустил?


 
antonn ©   (2006-02-22 09:32) [1]

__DATA__   (22.02.06 8:30)
Хочу сделать потдержку нескольких языков в программе, текущий язык сохраняю так :

а зачем так сохранять текущий язык со всех контроллов?
допустим, имеется несколько файлом с различными переводами, запоминаем, какой из файлов был загружен последним, и при запуске программы его и грузим. И сохраняем только имя файла, а не все текста. Сами файлы не нужно перезаписывать.


 
__DATA__   (2006-02-22 11:00) [2]

Я тоже сначало так хотел, только у меня много динамически создаваемых контролов, имя которых и заголовок которых я заранее не знаю, так что приходится при запуске сохранять все текущие имена контролов, а при смене языка востанавливать исходные имена контролов(которые были при запуске), а далее обрабатывать их примерно так :

for i := 0 to ComponentsCount-1 do
 if (Componets[i] is TButton) then
   (Components[i] as TButton).Caption := Translate("C:\Englesh.lng",(Components[i] as TButton).Caption;


где Translate :


function Tanslate(LangFile,World: String): String;
var
 strl,strl2: TStringList;
 i: Integer;
 b: Boolean;
begin
 try
   Result := World;
   strl := TStringList.Create;
   strl2 := TStringList.Create;
   if FileExists(LangFile) then
     strl.LoadFromFile(LangFile)
   else
     Exit;
   b := false;
   i := 0;
   while (i<strl.Count)and(not b) do
   begin
     strl2.Text := ExtractWorlds(strl.Strings[i],"=");
     if strl2.Count > 1 then
     begin
       if LStrCmpI(PChar(strl2.Strings[0]),PChar(World))=0 then
       begin
         Result := strl2.Strings[1];
         b := true;
       end;
     end;
     Inc(i);
   end;
 finally
   strl.Free;
   strl2.Free;
 end;
end;


и содержимое файла C:\Englesh.lng примерно следующее:


Собока=Dog
Кошки=Cats
...


Тоесть в файле с языком я не привязываю конкретному элементу конкретный заголовок, а перевожу все заголовки, также как переводчик

При этом можно без опасений работать с динамически создаваемыми контролами

А ошибку уже нашел, у меня оказывается в некоторых контролах поле Name было пустым, а при вызове WriteString с пустым именем секции как раз и вылетает AV. Так что теперь проверяю, чтобы Name пустым небыло


 
evvcom ©   (2006-02-22 11:16) [3]

[0] - код очень не эффективный и при добавлении компонент других типов автоматом их не распознает. Есть такой unit TypInfo. Обрати внимание, например, на GetStrProp и SetStrProp для получения/записи свойства Caption у контрола. И GetPropInfo для определения есть ли такое свойство у контрола и какого оно типа.


 
Экспериментатор   (2006-02-22 22:11) [4]

Вырезка из кода программы
function TranslateProp(Dict : TIniFile; ASection, AIdent1, AIdent2 : string;
                                               var AValue : string): boolean;
begin
 Result:=False;
 try
   if AIdent1="" then Exit;
   AValue:=Dict.ReadString(ASection, AIdent1+"."+AIdent2, "");
   if AValue="" then Dict.WriteString(ASection, AIdent1+"."+AIdent2, "")
     else Result:=True;
 except
 end;
end;

procedure TranslateFormControls(AForm : TForm; ADictFileName : string;
                             isTranslateCaption : boolean = True);
var Dict : TIniFile;
   I : Integer;
   Obj : TComponent;
   PropInfo1 : PPropInfo;
   PropInfo2 : PPropInfo;
   AValue : string;
begin
 try
   Dict:=TIniFile.Create(ExtractFilePath(ParamStr(0))+ADictFileName);

   if not FileExists(ExtractFilePath(ParamStr(0))+ADictFileName) then Exit;

   if isTranslateCaption and TranslateProp(Dict, AForm.Name ,"Form","Caption", AValue) then
         AForm.Caption:=AValue;

   { Переводим заголовки компонентов формы}
   for I:=0 to AForm.ComponentCount-1 do
   begin
     Obj:=AForm.Components[i];
     PropInfo1:=GetPropInfo(Obj.ClassInfo, "Action");
//      if (PropInfo_Action<>nil) then ShowMessage("Type="+IntToStr(Ord(PropInfo_Action.PropType^.Kind)));
     if (PropInfo1=nil) or
       ((PropInfo1<>nil) and (PropInfo1.PropType^.Kind = tkClass)
         and (GetObjectProp(Obj, "Action", TAction)=nil)) then
     begin
       PropInfo2:=GetPropInfo(Obj.ClassInfo, "Caption");
       if PropInfo2<>nil then
       begin
         if (PropInfo2^.PropType^.Kind=tkLString) and ((GetStrProp(Obj, "Caption")<>"")
         and (GetStrProp(Obj, "Caption")<>"-")) then
          if TranslateProp(Dict, AForm.Name ,Obj.Name, "Caption", AValue) then
            SetStrProp(Obj, PropInfo2, AValue);
       end;

       PropInfo2:=GetPropInfo(Obj.ClassInfo, "Hint");
       if PropInfo2<>nil then
       begin
         if (PropInfo2^.PropType^.Kind=tkLString) and (GetStrProp(Obj, "Hint")<>"")then
          if TranslateProp(Dict, AForm.Name ,Obj.Name,"Hint", AValue) then
            SetStrProp(Obj, PropInfo2, GetTextWithReturn(AValue));
       end;
     end;

     PropInfo2:=GetPropInfo(Obj.ClassInfo, "Title");
     if PropInfo2<>nil then
     begin
       if (PropInfo2^.PropType^.Kind=tkLString) and (GetStrProp(Obj, "Title")<>"")then
        if TranslateProp(Dict, AForm.Name ,Obj.Name,"Title", AValue) then
          SetStrProp(Obj, PropInfo2, AValue);
     end;

     PropInfo2:=GetPropInfo(Obj.ClassInfo, "Filter");
     if PropInfo2<>nil then
     begin
       if (PropInfo2^.PropType^.Kind=tkLString) and (GetStrProp(Obj, "Filter")<>"")then
        if TranslateProp(Dict, AForm.Name ,Obj.Name,"Filter", AValue) then
          SetStrProp(Obj, PropInfo2, AValue);
     end;
   end;
   { Переводим подсказки компонентов формы}
{    for I:=0 to AForm.ComponentCount-1 do
   begin
     Obj:=AForm.Components[i];
     PropInfo2:=GetPropInfo(Obj.ClassInfo, "Hint");
     if PropInfo2<>nil then
     begin
       if (PropInfo2^.PropType^.Kind=tkLString) and (GetStrProp(Obj, "Hint")<>"") then
        if TranslateProp(Dict, AForm.Name ,Obj.Name+".Hint", AValue) then
          SetStrProp(Obj, PropInfo2, AValue);
     end;
   end;}

   Dict.Free;
 except
//    ShowMessage("Language file is not loaded!");
 end;
end;


 
Экспериментатор   (2006-02-22 22:45) [5]

Файл перевода получится типа:

[frm_Main]
menu_File.Caption=Файл
menu_Search.Caption=Поиск
menu_View.Caption=Вид
menu_Options.Caption=Опции
menu_Operations.Caption=Операции
menu_Utility.Caption=Утилиты
menu_About.Caption=?
menu_Alternate.Caption=Альтернатива
menu_Language.Caption=Язык интерфейса
menu_LanguageStandard.Caption=Английский (стандартный перевод)
a_files_item_New.Caption=Новый...
a_files_item_New.Hint=Новый проект
a_files_item_Open.Caption=Открыть...
a_files_item_Open.Hint=Открыть проект
a_files_item_OpenDefault.Caption=Открыть файл по умолчанию
a_files_item_OpenDefault.Hint=Открыть файл по умолчанию
a_files_item_CloseFile.Caption=Закрыть файл

Позиции создаются автоматом
потом меняешь значение на свой вкус
Copyright(c) Экспериментатор


 
QwertyKz ©   (2006-02-23 05:43) [6]

GnuGetText - Хорошая вещь для локализации приложений
http://dybdahl.dk/dxgettext/docs/ -
На DelphiPlus.org была статья на эту тему, советую посмотреть


 
TStas ©   (2006-02-23 18:58) [7]

Я в инишку писал только сам язык, а в SetLanguage все и переводил. ИМХО Удобнее всего



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.03.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.05 c
6-1134481685
KosTiger
2005-12-13 16:48
2006.03.26
Сервер авторизации


1-1140431149
VEZ
2006-02-20 13:25
2006.03.26
TActionToolBar


15-1141222463
Amerzone
2006-03-01 17:14
2006.03.26
Вопрос про возможности VS 2005


9-1126253501
RzCoDer
2005-09-09 12:11
2006.03.26
ладшафт в OpenGL


2-1141896299
Der Nechk@ssoff
2006-03-09 12:24
2006.03.26
рисование кнопки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский