Jeg har også en menu i mit program, som der under kørsel ændres, så der tilføjes nye punkter. Jeg vil godt have, at når jeg genstarter programmet med ovenstående kode, at denne menu ikke slettes. Så jeg skal altså finde en måde at få den med. Nogen forslag?
Jeg skal vel så gemme name, caption, tag og onclick. jeg prøver:
Ini.WriteString('hej','noget',opsledeord1.Items[i].name); //navnet Ini.WriteString('hej','noget',opsledeord1.Items[i].Caption); //caption men hvad så?....
procedure Tform1.inigem(sender: tobject); var antal,i: integer; ini: Tinifile; begin antal:=opsledeord1.Count; if antal=0 then exit; Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); try for i:=0 to antal-1 do begin Ini.WriteString('hej','noget',opsledeord1.Items[i].name); Ini.WriteString('hej','noget',opsledeord1.Items[i].Caption); ini.WriteInteger('a','b',opsledeord1.Items[i].tag); Ini.WriteString('hej','noget','opslagnummervalg'); end; finally ini.Free; end; end;
bare lige for at du ikke sidder og bruger lang tid på et svar. det virker rimeligt nu. der skal lige ændres lidt. her er resultatet
procedure Tform1.hent(sender: Tobject); var Ini: TIniFile; lavmenu: tmenuitem; i: integer; begin if gemmenummer=1 then begin Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); try for i:=Ini.ReadInteger('hej','antal',0) downto 1 do begin lavmenu:=TMenuItem.Create(self); opsledeord1.add(lavmenu); lavmenu.Name:=Ini.ReadString('hej','navn'+inttostr(i),''); lavmenu.Caption:=Ini.ReadString('hej','caption'+inttostr(i),''); lavmenu.Tag:=Ini.ReadInteger('hej','tag'+inttostr(i),0); lavmenu.OnClick:=opslagnummervalg; lavmenu.MenuIndex:=0; end; finally ini.Free; end; end; end;
procedure Tform1.inigem(sender: tobject); var antal,i: integer; ini: Tinifile; begin antal:=opsledeord1.Count; if antal=0 then exit; Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); try Ini.WriteInteger('hej','antal',antal); for i:=0 to antal-1 do begin Ini.WriteString('hej','navn'+inttostr(i),opsledeord1.Items[i].name); Ini.WriteString('hej','caption'+inttostr(i),opsledeord1.Items[i].Caption); ini.WriteInteger('hej','tag'+inttostr(i),opsledeord1.Items[i].tag); end; finally ini.Free; end; end;
Jeg ved ikke helt med point, fordi rigtig nok gav du mig løsningen, men dit svar er ikke ligefrem 60 værd. Du kan få 20 point, som tak for det gode tip. Jeg giver point i morgen aften, så svar inden da. Her er det færdige resultat.
procedure Tform1.hent(sender: Tobject); var Ini: TIniFile; lavmenu: tmenuitem; i,check: integer; begin if gemmenummer=1 then begin Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); try check:=Ini.ReadInteger('hej','antal',0); if check>0 then for i:=Ini.ReadInteger('hej','antal',0) downto 1 do begin lavmenu:=TMenuItem.Create(self); opsledeord1.add(lavmenu); lavmenu.Name:=Ini.ReadString('hej','navn'+inttostr(i-1),''); lavmenu.Caption:=' '+Ini.ReadString('hej','caption'+inttostr(i-1),''); lavmenu.Tag:=Ini.ReadInteger('hej','tag'+inttostr(i-1),0); lavmenu.OnClick:=opslagnummervalg; lavmenu.MenuIndex:=0; end; finally ini.Free; end; end; end;
procedure Tform1.inigem(sender: tobject); var antal,i: integer; ini: Tinifile; begin antal:=opsledeord1.Count; Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); if antal=0 then begin try Ini.WriteInteger('hej','antal',antal); finally ini.Free; end; exit; end else try Ini.WriteInteger('hej','antal',antal); for i:=0 to antal-1 do begin Ini.WriteString('hej','navn'+inttostr(i),opsledeord1.Items[i].name); Ini.WriteString('hej','caption'+inttostr(i),opsledeord1.Items[i].Caption); ini.WriteInteger('hej','tag'+inttostr(i),opsledeord1.Items[i].tag); end; finally ini.Free; end; end;
Er det kun her i Eksperten at du undlader at indrykke? Håber ikke din "rigtige" kode ser sådan ud.
Den kunne i øvrigt optimeres en del:
const IniSection = 'hej'; // Noget du bruger flere gange bør være en konstant
// Når den komplementære funktion hedder IniGem så må denne hedde IniHent procedure Tform1.IniHent(Sender: Tobject); var i : integer; Ini: TIniFile; MenuItem: TMenuItem; // Et bedre navn end det du havde fundet begin // Du bør undgå globale variable, men hvis den er "private" under // TForm1 så bør den starte med f: fGemmeNummer (en defacto standard) if fGemmeNummer = 1 then begin Ini := TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); try for i := Ini.ReadInteger(IniSection,'antal',0) downto 1 do begin MenuItem := TMenuItem.Create(self); MenuItem.Name := Ini.ReadString(IniSection,'navn'+IntToStr(i-1),''); MenuItem.Caption := ' '+Ini.ReadString(IniSection,'Caption'+IntToStr(i-1),''); MenuItem.Tag:=Ini.ReadInteger(IniSection,'Tag'+IntToStr(i-1),0); MenuItem.OnClick := opslagnummervalg; MenuItem.MenuIndex := 0;
// Tilføj først når du er sikker på alt er OK opsledeord1.add(MenuItem); end; finally ini.Free; end; end; end;
procedure Tform1.IniGem(Sender: tobject); var ini: Tinifile; antal,i: integer; begin antal := opsledeord1.Count; Ini:=TIniFile.Create(ChangeFileExt(Application.ExeName,'.INI')); try Ini.WriteInteger(IniSection,'antal',antal); for i := 0 to antal - 1 do begin Ini.WriteString(IniSection,'navn'+IntToStr(i),opsledeord1.Items[i].Name); Ini.WriteString(IniSection,'caption'+IntToStr(i),opsledeord1.Items[i].Caption); Ini.WriteInteger(IniSection,'tag'+IntToStr(i),opsledeord1.Items[i].Tag); end; finally ini.Free; end; end;
Endelig bør du bruge store bogstaver noget mere. inttostr er lettere at genkende når den står som IntToStr.
jeg ved det - jeg har en hæslig orden. jeg må nok hellere tage mig sammen på det punkt. Jeg har nu erstattet mit med dit.
// Du bør undgå globale variable, men hvis den er "private" under // TForm1 så bør den starte med f: fGemmeNummer (en defacto standard)
'Gemmenummer' bruger jeg også i andre procedurer. Jeg har ærligt talt ikke forstået forskellen på Private, Public og andet. Du er velkommen til at forklare :)
Nu er det ret svært at give point, når man ikke har nogen ide om, hvor svært noget er. Jeg tvivler på, at Psycosoft-funware bliver sur over, at jeg ikke vil give ham 60 point for rådet "skriv det til en ini fil :)" men kun 20. Angående min tankevirksomhed før jeg stillede spørgsmålet: Naturligvis kan jeg tænke mig mere om selv - men så kan jeg jo så også løse alle problemer selv. Det smarte ved Eksperten er, at jeg ikke behøver at udforske en hel ny verden men i stedet bare spørge andre til råds. Hvis jeg skulle have tænkt mig frem til at bruge en ini-fil, havde det nok taget en del tid, idet jeg ikke anede, hvad en ini-fil er og kan bruges til. Faktisk mener jeg, at jeg har tænkt mig en del om selv: I stedet for bare at spørge, hvad en ini-fil er, da Psycosoft-funware svarede, undersøgte jeg det, og fik efterhånden lavet en rimelig og brugbar løsning selv. Jeg finder det fuldt ud rimeligt, at jeg ikke giver fuldt point i denne situation. Nu er det jo ikke sådan, at jeg prøve at lokke folk til at svare og så herefter nægter at give fuldt point. Pointene angiver, hvor meget tid jeg regner med, at folk bruger på besvarelsen. Hvis en person så bruger meget mindre tid, vil jeg ikke give fuldt point, ligesom hvis en person bruger meget mere, giver jeg gerne flere point.
Det er så min mening - håber ikke at nogen er blevet stødt.
Min kommentar lød lidt negativ, hvilket egentlig ikke var meningen, men nu er det jo ikke første gang du tager point tilbage ;-) Og hvad er pointene egentlig værd ? Det er voldsomt begrænset hvad de kan bruges til.
Men jeg synes der er noget principielt forkert i at stille point i udsigt - og så trække dem tilbage igen. Der kan være mange 'ude omkring' der bruger rigtig meget tid på overvejelser omkring et spørgsmål, og så gider spørgsmålstilleren ikke engang skrive svaret når han selv finder løsningen.
Alt det her med OO er noget med at indkapsle data i klasser så brugeren kun ser det relevante og ikke skal bekymre sig om hvordan den er lavet - bare den gør det den skal. Derfor har man synligheds-operatorerer på klassedefinitionen. Med delphi 2006 er "strict" kommet til.
Bemærk, at i nedenstående bruger jeg ordet "variable". I objektorienteret sammenhæng hedder de "attributter".
De forskellige properties, procedurer og funktioner er bare skitseringer af hvordan man opbygger klassen.
type TTestKlasse = class private // Variable her kan ses af klassen selv, samt andre klasser der ligger i samme // unit (fil). Bør begynde med et "f". Jeg foretrækker selv et lille, mens // resten af verdenen foretrækker et stort. Synes et stort F forstyrrer koden :-) fNavn : string; fPassword : string; procedure SetNavn(const Value : string); function GetPassword : string; strict private // Variable her kan KUN ses af klassen selv. fPassword : string; protected // Variable her kan ses af klassen selv, samt andre klasser der ligger i samme // unit (fil). Desuden kan klasser der nedarver fra TTestKlasse se dem. strict protected // Variable her kan KUN ses af klassen selv og i klasser der nedarver fra den. published // Bruges i forbindelse med disciplinen at lave komponenter. Variable her ses i // ObjectExploreren (F11) public // Ses af alle. Her bør man lave properties der tilgår de private variable man har // liggende.
a nor>> Fint nok. Jeg er nu uenig - men som sagt, så handler det om principper, og vi har bare forskellige. Jeg vil dog gerne medgive, at man bør skrive, når man har fundet svaret. Det mener jeg nu også, at jeg altid har gjort, og jeg holdt da også psycosoft-funware underrettet om, hvor langt jeg var kommet i processen hele tiden.
I øvrigt vil jeg godt bede om forladelse om mit krav "Jeg giver point i morgen aften, så svar inden da. " Det var egentlig ikke rimeligt.
hrc >> Tak. Overskueligt opsat og forklaret.
Nå,jeg må hellere give de point efterhånden. hrc du må godt ligge et svar. psycosoft-funware du er stadig velkommen til at få point, selv om du pænt har afslået :) - det var jo et ret godt tip. Men ellers får hrc dem bare.
stod det til mig blev pointsystemet her på E sprunget i luften, jeg er rigeligt tilfreds med at få at vide af folk at mine inlæg har kunne hjælpe dem på rette spor :)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.