![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Сохранение заголовков всех компонентов формы
__DATA__ © (2006-02-22 08:30:00)Хочу сделать потдержку нескольких языков в программе, текущий язык сохраняю так :
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 вылетать не должен, что я упустил?
TStas (2006-02-23 18:58:00) [1]Я в инишку писал только сам язык, а в SetLanguage все и переводил. ИМХО Удобнее всего
QwertyKz (2006-02-23 05:43:00) [2]GnuGetText - Хорошая вещь для локализации приложений
http://dybdahl.dk/dxgettext/docs/-
На DelphiPlus.org была статья на эту тему, советую посмотреть
Экспериментатор (2006-02-22 22:45:00) [3]Файл перевода получится типа:
[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) Экспериментатор
Экспериментатор (2006-02-22 22:11:00) [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;
evvcom (2006-02-22 11:16:00) [5][0] - код очень не эффективный и при добавлении компонент других типов автоматом их не распознает. Есть такой unit TypInfo. Обрати внимание, например, на GetStrProp и SetStrProp для получения/записи свойства Caption у контрола. И GetPropInfo для определения есть ли такое свойство у контрола и какого оно типа.
__DATA__ (2006-02-22 11:00:00) [6]Я тоже сначало так хотел, только у меня много динамически создаваемых контролов, имя которых и заголовок которых я заранее не знаю, так что приходится при запуске сохранять все текущие имена контролов, а при смене языка востанавливать исходные имена контролов(которые были при запуске), а далее обрабатывать их примерно так :
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 пустым небыло
antonn (2006-02-22 09:32:00) [7]__DATA__ (22.02.06 8:30)
Хочу сделать потдержку нескольких языков в программе, текущий язык сохраняю так :
а зачем так сохранять текущий язык со всех контроллов?
допустим, имеется несколько файлом с различными переводами, запоминаем, какой из файлов был загружен последним, и при запуске программы его и грузим. И сохраняем только имя файла, а не все текста. Сами файлы не нужно перезаписывать.