Witam,
piszę pewien program, który na starcie wczytuje ustawienia, a wraz z ustawieniami tłumaczenie wybranego przez użytkownika języka. Wszelakie ustawienia, oraz tłumaczenia wczytuje z XML'a. Początkowo strukturę XML'a tłumaczenia podzieliłem na coś takiego:
<MenuForm>
<Buttons>
<Caption name="sbCut" trans="Cut" />
<Caption name="sbPaint" trans="Paint Edit" />
<Caption name="sbCancel" trans="Cancel" />
<Caption name="sbUpload" trans="Upload" />
<Caption name="sbSave" trans="Save" />
</Buttons>
</MenuForm>
Gdzie atrybut name to nazwa komponentu, a trans to tłumaczenie. Jednakże z czystej ciekawości postanowiłem sprawdzić czy można to zrobić w ten sposób:
<MenuForm>
<Caption name="sbCut" trans="Cut" />
<Caption name="sbPaint" trans="Paint Edit" />
<Caption name="sbCancel" trans="Cancel" />
<Caption name="sbUpload" trans="Upload" />
<Caption name="sbSave" trans="Save" />
<Caption name="rTest" trans="Test" />
<Caption name="lTest" trans="Test2" />
</MenuForm>
Ideą było, by grupować tłumaczenia jedynie po właściwości, którą będę modyfikował (w tym wypadku Caption), a nie jak wyżej po danej klasie. Dzięki temu oszczędziłbym dużo czasu. Tak więc napisałem mniej więcej coś takiego:
const
XML_LANG_CAPTION = 'Caption';
XML_A_NAME = 'name';
XML_A_TRANS = 'trans';
var
Obj: TObject;
TransNode: IXMLNODE;
[...]
TransNode:=ClassNode.ChildNodes.First;
repeat
if(TransNode.LocalName=XML_LANG_CAPTION)then begin
Obj:=MenuForm.FindComponent(TransNode.Attributes[XML_A_NAME]);
if(Assigned(Obj))then
TLabel(Obj).Caption:=TransNode.Attributes[XML_A_TRANS]
else
raise Exception.Create(E_XML_LOAD);
end;
TransNode:=TransNode.NextSibling;
until(TransNode=nil);
Nie wpadłem na lepszy pomysł, jak na rzutowanie obiektu Obj na jakiś pierwszy lepszy komponent, który posiada właściwość Caption, w tym wypadku TLabel. Muszę przyznać, że przed wciśnięciem F9 byłem pewny, że nie zadziała, a tu ku mojemu zaskoczeniu Captiony zostały zmienione według tłumaczeń, żadnych błędów - przynajmniej na razie. Dodam, że wcześniej próbowałem zamiast:
TLabel(Obj).Caption
zrobić w ten sposób:
(Obj as TLabel).Caption
W ten sposób co prawda się kompilowało, jednak na tym koniec.
Założyłem ten wątek by dowiedzieć się czy jest to bezpieczny sposób, a jeśli nie - w jaki inny sposób można to wykonać, czy po prostu grupować względem klas?
PS. Mam nadzieję, że wszystko wyjaśniłem i wiadomo o co chodzi, umysł już na dzisiaj ma dosyć, a nie mogę z tym zwlekać.
nil
.abrakadaberclass or object types are not releated
; http://pastebin.com/9dYGdZ67abrakadaber