[Delphi] Runtime strtoobj-alike functie

Pagina: 1
Acties:

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Juist,

beetje moeilijk te begrijpen die titel.. maar hoe noem je het...

ik zal even uitleggen wat ik bedoel..
stel ik heb een string genaamd test1, met de waarde 'label1'.

nu wil ik dus dat label1 eruit worg gelezen en dat hij dat als het aanwezige object label1 herkent... dus dat ik bijvoorbeeld label1.caption kan wijzigen.

dus uit een volgende tekst bestand zou ik dus makkelijk aanpassingen kunnen maken (tijdens het runnen van een programma)
code:
1
2
3
label1 = blaaat
label2 = eoe..
label3 = Got ofzo?

dus moet het programma label 1 t/m 3 de caption veranderen.

is dut dus uberhaupt mogelijk zonder het gewoon grofweg te doen als in:
Delphi:
1
2
3
if id= 'label1' then label1.caption := content
else if id= 'label2' then label2.caption := content
else if id= 'label3' then label3.caption := content;


Dus ik ben benieuwd in hoevere dit mogelijk is?

Ik hoop alleen dat mijn verhaal duidelijk genoeg is.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Gebruik de tag property van TLabel om er een integer aan te hangen en compare vervolgens die ints.

Professionele website nodig?


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
juist.. daar had ik ook al eens naar gekeken.. maar dan de vraag... hoe maak je een mooie for/while loop waarin hij alle componenten (dus ook knoppen / Tedit's enzo) afgaat op een tag... of kun je laten zoeken op die tag?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Recursief vanaf je TForm naar beneden loopen over de 'Controls' arrays?

Professionele website nodig?


Verwijderd

findcomponent ofzo,ff zoeken, heb geen delphi hier op m'n machine staan.


code:
1
2
3
4
5
6
7
8
procedure SetLabelContent(LabelName : string; Content : string);
var
 MyLabel : TLabel;
begin
 MyLabel := FindComponent(LabelName);
 if MyLabel <> nil then
   MyLabel.Caption := Content;
end;


ff uit het hoofd, dus niet foutvrij waarschijnlijk.

[ Voor 74% gewijzigd door Verwijderd op 15-08-2003 12:22 ]


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure TForm1.Button2Click(Sender: TObject);
var
  found:bool;
const
  NamePrefix = 'Label1';
begin
found:=false;
while not found do begin
    with TLabel(FindComponent(NamePrefix)) do
    begin
      caption:='blaat';
      found := true;
    end;
  end;
end;


nou bedankt voor de laatste kick in de richting.. dit werkt.. nu het nog even schrijven voor alle componenten.
Verwijderd schreef op 15 augustus 2003 @ 12:15:
findcomponent ofzo,ff zoeken, heb geen delphi hier op m'n machine staan.


code:
1
2
3
4
5
6
7
8
procedure SetLabelContent(LabelName : string; Content : string);
var
 MyLabel : TLabel;
begin
 MyLabel := FindComponent(LabelName);
 if MyLabel <> nil then
   MyLabel.Caption := Content;
end;


ff uit het hoofd, dus niet foutvrij waarschijnlijk.
juist, zoiets kan ik inderdaad gebruiken ja, nu nog even voor edit en knopjes een aparte functie maken. maar voor de rest, bedankt voor de hulp.

[ Voor 48% gewijzigd door Dala op 15-08-2003 12:28 ]


Verwijderd

Ik begrijp je while lus niet helemaal.

wat betreft alle componenten :

Je kan het opsplitsen, meeste componenten gebruiken Caption,
krijg je iets van

code:
1
2
3
4
5
6
7
var
 MyComp:TComponent;
begin
   MyComp := FindComponent ( compName );
   if myComp.ClassName in ['TLabel', 'TMemo', 'TButton] then
      MyComp.Caption  :=  compContent; 
end;

[ Voor 8% gewijzigd door Verwijderd op 15-08-2003 12:33 ]


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
oja.. dat scheelt ja..

en inderdaad mijn while lus is overbodig...

ik heb jou functie gewoon even aangepast..

die while functie van mij was gewoon nog uit de help file van delphi
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.SetLabelCaption(LabelName : string; Content : string);
var
 MyLabel : TLabel;
begin
try
 with TLabel(FindComponent(labelname)) do
  caption:=Content;
 end;
finally
 Mylabel.Free;
end;
end;

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Constant stringcompares over al je componenten doen kan aardig in de CPU-tijd lopen, vandaar mijn voorstel om hetzelfde te doen met de Tag... kan enorme tijden schelen.

Professionele website nodig?


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
zojuist in de help van delphi gekeken... Tag is dus geen zoek functie voor.

want als via tag sneller gaat.. dan scheelt het wel wat ja.. en is dus belangrijk

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
curry684 schreef op 15 augustus 2003 @ 12:14:
Recursief vanaf je TForm naar beneden loopen over de 'Controls' arrays?
klinkt misschien een beetje gek, maar ik krijg dit maar niet werkend?

zou je misschien een beejte hulp kunnen bieden?

wat ik begrijp is dus dat ik gewoon een lus moet maken die gewoon alle componenten in m'n form afgaat en de tag checked of het de genadigde is, en dan dat component aanpassen en lus stoppen. maar hoe waar krijg ik de lijst van al m'n componenten en hoe kan ik die compleet laten aflopen?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Ik ken geen Delphi, maar in C++:
C++:
1
2
3
4
5
6
7
8
9
10
11
TControl* FindByTag(TControl* p_Root, int p_Tag)
{
if(p_Root->Tag == p_Tag)
  return p_Root;
for(int i = 0; i != p_Root->ControlCount; i++)
  {
  TControl* l_Control = FindByTag(p_Root->Controls[i], p_Tag);
  if(l_Control) return l_Control;
  }
return NULL;
}

[ Voor 5% gewijzigd door curry684 op 15-08-2003 13:12 ]

Professionele website nodig?


Verwijderd

curry684 schreef op 15 August 2003 @ 12:37:
Constant stringcompares over al je componenten doen kan aardig in de CPU-tijd lopen, vandaar mijn voorstel om hetzelfde te doen met de Tag... kan enorme tijden schelen.
Als het goed is doe je dit soort zaken ook niet constant.
Als je het constant gaat doen (dus constant updaten) moet je idd
een andere oplossing zoeken.

Je zou er aan kunnen denken om dan een soort caching op te zetten v/d
te wijzigen objecten. Met een stringlist die een pointer bij houdt naar het
betreffende object ofzo.

[ Voor 18% gewijzigd door Verwijderd op 15-08-2003 13:21 ]


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Verwijderd schreef op 15 augustus 2003 @ 13:20:
[...]


Als het goed is doe je dit soort zaken ook niet constant.
Als je het constant gaat doen (dus constant updaten) moet je idd
een andere oplossing zoeken.

Je zou er aan kunnen denken om dan een soort caching op te zetten v/d
te wijzigen objecten. Met een stringlist die een pointer bij houdt naar het
betreffende object ofzo.
ik doe het inderdaad niet constant, ik gebruik het voor een programma dat in meerdere talen mogelijk word. en dus moet er ergens de mogelijk heid zijn om het te switchen.

Verwijderd

Dala schreef op 15 August 2003 @ 13:23:
[...]
ik doe het inderdaad niet constant, ik gebruik het voor een programma dat in meerdere talen mogelijk word. en dus moet er ergens de mogelijk heid zijn om het te switchen.
Hier zijn al een aantal kant en klare componenten voor, ik weet de Delphi methode zelf, is nogal omslachtig, maar er zijn genoeg alternatieven te vinden, zowel free/shareware als commercieel.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18-08 21:00

Creepy

Tactical Espionage Splatterer

Dala schreef op 15 August 2003 @ 13:23:
[...]


ik doe het inderdaad niet constant, ik gebruik het voor een programma dat in meerdere talen mogelijk word. en dus moet er ergens de mogelijk heid zijn om het te switchen.
Je wilt dit gebruiken om makkelijk van taal te kunnen wisselen? Kijk eens naar resource DLL's. In een aantal Delphi tutorials en boeken worden deze gebruikt om een programma te maken en beschikbaar te maken in meerdere talen. Delphi (in elk geval versie 6 en hoger) heeft hier ook een leuke optie voor beschikbaar. In delphi: Project -> Languages -> Add, nog wat talen selecteren, alle files saven, en tada, er verschijnt een tool om alles te kunnen vertalen.

EN natuurlijk omdat je als programmeur de namen van de componenten al weet kan je ook je componenten wel benaderen zonder dat je dat moet doen met alleen een string waar de naam van het component in zit (en dus ook zonder findcomponent, of components[])

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Creepy schreef op 15 augustus 2003 @ 13:39:
[...]

Je wilt dit gebruiken om makkelijk van taal te kunnen wisselen? Kijk eens naar resource DLL's. In een aantal Delphi tutorials en boeken worden deze gebruikt om een programma te maken en beschikbaar te maken in meerdere talen. Delphi (in elk geval versie 6 en hoger) heeft hier ook een leuke optie voor beschikbaar. In delphi: Project -> Languages -> Add, nog wat talen selecteren, alle files saven, en tada, er verschijnt een tool om alles te kunnen vertalen.
Ik vind dat ding niet zo soepel werken.

En makkelijkst is toch om met losse files, tekst,xml te werken, zodat meerdere mensen, ook mensen die geen toegang hebben tot de code/dll's kunnen
vertalen.
EN natuurlijk omdat je als programmeur de namen van de componenten al weet kan je ook je componenten wel benaderen zonder dat je dat moet doen met alleen een string waar de naam van het component in zit (en dus ook zonder findcomponent, of components[])
Dan kan je dit gebruiken (gevonden met google):

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Procedure SetProperty(Sender:TComponent
                      ;sPropName:String
                      ;vValue:Variant)
Var
   PropInfo : PPropinfo;
Begin
    // From the class information, get the property
    PropInfo := GetPropInfo(Sender.ClassInfo, 
                            sPropName);

    // Does the property exist?
    If (PropInfo <> Nil) Then Begin
       Case propinfo^.PropType^.Kind Of

          tkEnumeration,tkInteger:
             Begin
                SetOrdProp(Sender,PropInfo,vValue);
             End;

          tkString,tkLString,tkWString:
             Begin
                SetStrProp(Sender,PropInfo,vValue);
             End;
       End;
    End;
End;


Hierbij loop je dus over alle je components heen, de vertaling lees je eerst in een een Stringvaluelist (ComponentNaam=Property1:Value,Property2:Value),
je zoekt je component op in de stringvalue list, en zet de property's.
Zo kan je dus ook meerdee property's gaan veranderen.

[ Voor 9% gewijzigd door Verwijderd op 15-08-2003 13:51 ]


  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
interne optie met dll's is niet van toepassing, want het moet door iedereen kunnen worden gewijzigd / vertaald.

ik ben nu gewoon bezig met findcomponent. Werkt mooi genoeg.

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 18-08 21:00

Creepy

Tactical Espionage Splatterer

Verwijderd schreef op 15 augustus 2003 @ 13:48:
[...]
Dan kan je dit gebruiken (gevonden met google):

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Procedure SetProperty(Sender:TComponent
                      ;sPropName:String
                      ;vValue:Variant)
Var
   PropInfo : PPropinfo;
Begin
    // From the class information, get the property
    PropInfo := GetPropInfo(Sender.ClassInfo, 
                            sPropName);

    // Does the property exist?
    If (PropInfo <> Nil) Then Begin
       Case propinfo^.PropType^.Kind Of

          tkEnumeration,tkInteger:
             Begin
                SetOrdProp(Sender,PropInfo,vValue);
             End;

          tkString,tkLString,tkWString:
             Begin
                SetStrProp(Sender,PropInfo,vValue);
             End;
       End;
    End;
End;


Hierbij loop je dus over alle je components heen, de vertaling lees je eerst in een een Stringvaluelist (ComponentNaam=Property1:Value,Property2:Value),
je zoekt je component op in de stringvalue list, en zet de property's.
Zo kan je dus ook meerdee property's gaan veranderen.
Eeeh.. dat soort dingen worden meestal gebruikt voor property editors (IProperty, TPropertyEditor). Lijkt me een beetje overkill?
En ik zal wel blind zijn maar ik heb geen SetStrProp of een losse GetPropInfo functie? Er is wel een GetPropInfo method (van TPropertyEditor en IProperty) maar die is iets anders gedefinieerd dan jij hem hier gebruikt ;)

Bij een property editor weet je lang niet altijd met welk (soort) component je vandoen hebt. Maar in dit geval weet je wel met wat voor soort componenten je van doen hebt en welke properties je wilt gaan zetten.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Verwijderd

Creepy schreef op 15 August 2003 @ 14:08:
[...]

Eeeh.. dat soort dingen worden meestal gebruikt voor property editors (IProperty, TPropertyEditor). Lijkt me een beetje overkill?
En ik zal wel blind zijn maar ik heb geen SetStrProp of een losse GetPropInfo functie? Er is wel een GetPropInfo method (van TPropertyEditor en IProperty) maar die is iets anders gedefinieerd dan jij hem hier gebruikt ;)

Bij een property editor weet je lang niet altijd met welk (soort) component je vandoen hebt. Maar in dit geval weet je wel met wat voor soort componenten je van doen hebt en welke properties je wilt gaan zetten.
Ja klopt, is misschien niet het beste voorbeeld dit :),
(heb hier geen delphi bij de hand op het moment)

Bedoel meer deze:
SetPropValue (Component, PropertyName, PropertyValue);

Probleem is namelijk dat je soms wat meer en of andere dingen dan de caption moet veranderen. Een collega van me is hier mee bezig geweest trouwens en
heeft een zeer leuk component gemaakt. Weet niet of het vrij beschikbaar is.
Werkt met een centraal TranslateManager componenten, en op ieder form weer een Translator component.

[ Voor 17% gewijzigd door Verwijderd op 15-08-2003 14:31 ]


  • Delphi32
  • Registratie: Juli 2001
  • Laatst online: 10:56

Delphi32

Heading for the gates of Eden

Dala schreef op 15 August 2003 @ 12:35:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.SetLabelCaption(LabelName : string; Content : string);
var
 MyLabel : TLabel;
begin
try
 with TLabel(FindComponent(labelname)) do
  caption:=Content;
 end;
finally
 Mylabel.Free;
end;
end;
Deze is leuk, maar niet voor productie geschikt :) Wel heel geschikt om te laten zien hoe Windows 98 & ME op hun muil gaan als je in het wilde weg pointers gaat free-en. Krijg je heel onvoorspelbare resultaten van, altijd grappig.
Je declareert een var MyLabel, die vul je vervolgens niet (dus wijst ie naar een min of meer random adres) en aan het eind van je procedure free je dat ding. Dan gaat Delphi dus een TLabel voor je opruimen op een willekeurige plek.
Ik denk ik zeg het maar even, dit soort dingen kunnen een ramp zijn om terug te vinden ;)

  • Just_a_Gamer
  • Registratie: November 2001
  • Laatst online: 10:18
Laat staan dat ie de label niet kan vinden met de bijbehorende labelnaam. Een caption geven aan een nil object wil ook niet echt vlotten ( volgens mij hoor )

Verwijderd

--

[ Voor 100% gewijzigd door Verwijderd op 16-08-2003 14:20 ]


  • Just_a_Gamer
  • Registratie: November 2001
  • Laatst online: 10:18
Verwijderd schreef op 16 August 2003 @ 04:50:
[...]


ach nee , je meent het, wat ben jij goed. Zoek je nog een baan>
Ik geef het alleen maar aan. Ben je met de verkeerde been uit bed gestapt ofzo.

Verwijderd

Just_a_Gamer schreef op 16 August 2003 @ 10:51:
[...]


Ik geef het alleen maar aan. Ben je met de verkeerde been uit bed gestapt ofzo.
sorry :)

Verwijderd

Dala schreef op 15 August 2003 @ 13:23:
ik gebruik het voor een programma dat in meerdere talen mogelijk word. en dus moet er ergens de mogelijk heid zijn om het te switchen.
Als 't geld mag kosten is Multilizer een erg goede optie. Wel aan de prijs, maar ze leveren er bv. ook de vertaal-tool bij die je samen met je project file naar een vertaalbureau kunt sturen, ze ondersteunen dictionaries, etc.

Wil je zoiets zelf schrijven, dan zou ik niet gaan knoeien met tags, maar met een systeem dat op het OnCreate event (of in een eigen constructor) de components scant of ze naar jouw mening vertaalbare properties hebben, en vervolgens die vertaalbare properties (Caption, Hint, etc.) omzetten naar de taal die je wilt.

Maar dan ben je er nog niet...

- Je zult een goede opzet van je vertaal-bestanden op moeten zetten (ik zou 't nu in XML doen, al heb ik het toen -Delphi 2 tijd- in DFM-achtige syntax gedaan).

- Je zult een design-time tool moeten schrijven die alle vertaalbare componenten exporteert naar dat vertaal-bestand (of een losse tool die de dfm's in het project scant).

- En een utility voor de vertalers om de boel in te vullen is natuurlijk ook erg handig. Je kunt van een vertaler niet verwachten dat 'ie rechtstreeks in XML-files gaat editten en dat daarna die XML ook nog valid is. :)

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Delphi32 schreef op 16 augustus 2003 @ 00:03:
[...]

Deze is leuk, maar niet voor productie geschikt :) Wel heel geschikt om te laten zien hoe Windows 98 & ME op hun muil gaan als je in het wilde weg pointers gaat free-en. Krijg je heel onvoorspelbare resultaten van, altijd grappig.
Je declareert een var MyLabel, die vul je vervolgens niet (dus wijst ie naar een min of meer random adres) en aan het eind van je procedure free je dat ding. Dan gaat Delphi dus een TLabel voor je opruimen op een willekeurige plek.
Ik denk ik zeg het maar even, dit soort dingen kunnen een ramp zijn om terug te vinden ;)
jep.. het is inderdaad een baggere code.. die was gewoon even uit de help aangepast... en inderdaad heb ik al die free enzo weggelaten. nu is ie veel korter...

misschien is een betaalbaar iets anders een idee.. doet dat programma ook je showmessage(blaaat); tekst opzoeken en zo nodig aanpassen?

op het moment heb ik een redelijk simpele bestands structuur:
code:
1
2
{start button}Klik hier om te starten
{cancel button}Klik hier om te stoppen

effe voor de duidelijkheid.. dis maar een voorbeeldje..

Verwijderd

Dala schreef op 17 augustus 2003 @ 22:57:
misschien is een betaalbaar iets anders een idee.. doet dat programma ook je showmessage(blaaat); tekst opzoeken en zo nodig aanpassen?
Sorry voor de late reactie, maar ik had niet door dat je 't tegen mij had. :)
Jep, Multilizer ondersteunt ook dat soort dictionary vertalingen, maar dan moet je 'm wel even helpen.
Dus ShowMessage(IvDictio.Translate('blaat')) i.p.v. ShowMessage('blaat').
op het moment heb ik een redelijk simpele bestands structuur:
code:
1
2
{start button}Klik hier om te starten
{cancel button}Klik hier om te stoppen

effe voor de duidelijkheid.. dis maar een voorbeeldje..
Mij ietsje te simpel voor een goed vertaalsysteem. Een simpele TButton heeft bv. al 2 properties die vertaald kunnen worden: Caption en Hint. En op form 2 kan {start button} wel een heel andere caption hebben dan op form 1.

Wel leuk, die curly brackets, trouwens. Doet me denken aan een vreselijk krachtig terminal-programma ({Commo}) dat ik jaren geleden gebruikte. Maar of dat nu nog handig is? Waarom geen XML?

  • Dala
  • Registratie: November 2000
  • Laatst online: 19-08 10:22
Verwijderd schreef op 18 August 2003 @ 22:24:
[...]

Sorry voor de late reactie, maar ik had niet door dat je 't tegen mij had. :)
Jep, Multilizer ondersteunt ook dat soort dictionary vertalingen, maar dan moet je 'm wel even helpen.
Dus ShowMessage(IvDictio.Translate('blaat')) i.p.v. ShowMessage('blaat').

[...]

Mij ietsje te simpel voor een goed vertaalsysteem. Een simpele TButton heeft bv. al 2 properties die vertaald kunnen worden: Caption en Hint. En op form 2 kan {start button} wel een heel andere caption hebben dan op form 1.

Wel leuk, die curly brackets, trouwens. Doet me denken aan een vreselijk krachtig terminal-programma ({Commo}) dat ik jaren geleden gebruikte. Maar of dat nu nog handig is? Waarom geen XML?
oja.. per form heb ik een apart nummer aan het begin van de vertaling staan:
code:
1
2
3
4
5
6
7
{1}Form1 tekst
{blaat:t}Dit staat op de knop
{blaat:h}Dit is de hint

{2}Form2 tekst
{blat:t}Dit staat op de knop
{blat:h}Dit is de hint


die {'s heb ik gesteeld van het subtitle format .sub (microdvd dacht ik).

de enigste reden dat ik nog geen xml gebruik is eigelijk erg simpel en lui, ik heb er nog geen ervaring mee, ik hoor inderdaad al van verschillende kanten XML.. maar dan ga ik misschien es binnenkort naar een bibiotheek om eens te lezen over het wonderbaarlijke XML... tot nu toe was ik gewoon te lui om eens te gaan lezen erover.
Pagina: 1