RTTI - Saber se a propriedade é um array de componentes
Bom Dia
Pessoal trabalho em uma empresa que tem filiais em outros países e devido a isso tenho que criar uma maneira de traduzir os captions do sistema para a linguagem do país. Como o sistema é antigo e não temos como utilizar a opção multi idiomas do delphi estamos criando uma forma de traduzir os captions em tempo de execução utilizando uma tradução que está no banco de dados, para isso estou utilizando RTTI. Porém estou tendo problemas com os componentes que possuem a propriedade Items.
Nos componentes que possuem essas propriedades eu também tenho que traduzir.
Nesta listagem entram os componentes como TComboBox, TGroupBox e TPopupMenu.
No TComboBox a propriedade Items é uma StringList (não tenho problema), porém no caso do TPopupMenu a propriedade Items é um array de outro componente (onde tenho problemas). Como posso fazer para saber qual das duas situações é utilizando RTTI e como posso fazer para alterar a propriedade caption do item do menu que está na propriedade Items?
Abaixo segue o código que estou utilizando
Pessoal trabalho em uma empresa que tem filiais em outros países e devido a isso tenho que criar uma maneira de traduzir os captions do sistema para a linguagem do país. Como o sistema é antigo e não temos como utilizar a opção multi idiomas do delphi estamos criando uma forma de traduzir os captions em tempo de execução utilizando uma tradução que está no banco de dados, para isso estou utilizando RTTI. Porém estou tendo problemas com os componentes que possuem a propriedade Items.
Nos componentes que possuem essas propriedades eu também tenho que traduzir.
Nesta listagem entram os componentes como TComboBox, TGroupBox e TPopupMenu.
No TComboBox a propriedade Items é uma StringList (não tenho problema), porém no caso do TPopupMenu a propriedade Items é um array de outro componente (onde tenho problemas). Como posso fazer para saber qual das duas situações é utilizando RTTI e como posso fazer para alterar a propriedade caption do item do menu que está na propriedade Items?
Abaixo segue o código que estou utilizando
procedure TSISFR022.FormCreate(Sender: TObject);
var
iCont: integer;
PropInfo: PPropInfo;
vSqlIdioma: string;
vItens: TStringList;
vTraduz: Boolean;
begin
vSqlIdioma := ''SELECT componente, traducao from tabela where form= ''+QuotedStr(''frmNotafiscal'')+'' and idioma = ''+QuotedStr(''es'');
if cdsTraduz.State = dsBrowse then
cdsTraduz.Close;
cdsTraduz.DataRequest(vSqlIdioma);
cdsTraduz.Open;
if cdsTraduz.RecordCount > 0 then
begin
//busca do banco
for iCont := 0 to (ComponentCount -1) do
begin
PropInfo := GetPropInfo(Components[iCont].ClassInfo, ''Caption'');
if PropInfo <> nil then
begin
if trim(GetPropValue(Components[iCont], ''Caption'')) <> '''' then
begin
if cdsTraduz.Locate(''componente'', Components[iCont].Name,[]) then
SetPropValue(Components[iCont], ''Caption'', cdsTraduz.FieldByName(''traducao'').AsString);
end;
end;
PropInfo := GetPropInfo(Components[iCont].ClassInfo, ''Items'');
if (PropInfo <> nil) then
begin
vItens := TStringList.Create;
vItens.Text := TStringList(Pointer(strtoint(GetPropValue(Components[iCont], ''Items'')))).Text;
vTraduz := False;
for iTotal := 0 to (vItens.Count - 1) do
begin
if cdsTraduz.Locate(''componente'', Components[iCont].Name+''_L''+IntToStr(iTotal+1),[]) then
begin
vItens[iTotal] := cdsTraduz.FieldByName(''traducao'').AsString;
vTraduz := True;
end;
end;
if vTraduz then
TStringList(TObject(Pointer(strtoint(GetPropValue(Components[iCont], ''Items''))))).Text:=vItens.Text;
FreeAndNil(vItens);
end;
end;
if cdsTraduz.State = dsBrowse then
cdsTraduz.Close;
end;
end;
Fernando Vicari
Curtidas 0
Respostas
Gustavo Bretas
19/11/2013
Fernando, no PopUp os Itens estão na lista dele, ok, mas vc consegue acessar o TMenuItem, e ele entra no primeiro FOR, insira o nome do componente na sua tabela de tradução que vai dar certo!
Mas se seu sistema tiver TreeView, complica um pouco! rsrs
Mas se seu sistema tiver TreeView, complica um pouco! rsrs
GOSTEI 0
Fernando Vicari
19/11/2013
Olá Bretas
Correta a sua observação, porém o problema é que para o componente TPopupMenu entra no segundo IF e não poderia.
Como posso saber quando pode entrar no segundo if e quando não? A única maneira que eu vi foi procurar por uma propriedade que tem no TPopupMenu (Ex.: MenuAnimation) e se existir não entra no segundo if, porém achei uma "gambiarra" fazer isso.
Sobre o TreeView também utilizo esse componente. Você pode me ajudar a tratar isso nele também?
Obrigado.
Correta a sua observação, porém o problema é que para o componente TPopupMenu entra no segundo IF e não poderia.
Como posso saber quando pode entrar no segundo if e quando não? A única maneira que eu vi foi procurar por uma propriedade que tem no TPopupMenu (Ex.: MenuAnimation) e se existir não entra no segundo if, porém achei uma "gambiarra" fazer isso.
Sobre o TreeView também utilizo esse componente. Você pode me ajudar a tratar isso nele também?
Obrigado.
GOSTEI 0
Gustavo Bretas
19/11/2013
Acho até que foge um pouco do RTTI, mas vc pode colocar um IF verificando a classe dos componentes que vc não quer que verifique os ITEMS!
Por exemplo:
TreeView não sei ainda como fazer! :(
Enquanto isso da uma olhada nesse tutorial: [url]http://www.sisulizer.com/translation/vcl/VCL.pdf[/url]
Por exemplo:
if (not Components[iCont].InheritsFrom(TTPopupMenu)) then
begin
PropInfo := GetPropInfo(Components[iCont].ClassInfo, '' Items '');
if (PropInfo <> nil) then
begin
vItens := TStringList.Create;
vItens.Text := TStringList(Pointer(strtoint(GetPropValue(Components[iCont], '' Items '')))).Text;
vTraduz := False;
for iTotal := 0 to (vItens.Count - 1) do
begin
if cdsTraduz.Locate('' componente '', Components[iCont].Name + '' _L '' + IntToStr(iTotal + 1), []) then
begin
vItens[iTotal] := cdsTraduz.FieldByName('' traducao '').AsString;
vTraduz := True;
end;
end;
if vTraduz then
TStringList(TObject(Pointer(strtoint(GetPropValue(Components[iCont], '' Items ''))))).Text := vItens.Text;
FreeAndNil(vItens);
end;
end;TreeView não sei ainda como fazer! :(
Enquanto isso da uma olhada nesse tutorial: [url]http://www.sisulizer.com/translation/vcl/VCL.pdf[/url]
GOSTEI 0