Avatar billede monie Nybegynder
14. februar 2004 - 17:47 Der er 21 kommentarer og
1 løsning

Error af INI file

Jeg har et problem her.
Når der Compiled er der ingen fejl
Men når kodeeksemplet nedenfor køres fremkommer der ef fejlmeddelse:

Se www.sunwind.dk/ErrorafINIfile.jpg

Men syndtes ikke denne meddelse fortæller hvor henne fejlen er.
Derfor håber du vil hjælpe mig.
Har du en ide til forbedering vil det glæde mig.
Ret venligst i koderne, det syndtes jeg giver det bedst resultat.

Det væsentelig i koderne:

public
  { Public declarations }
end;

var
fmFontOpsestning: TfmFontOpsestning;
FontName  : string;
FontSize  : Integer;
FontColor  : string;
Bibliotek, Kl, Dato : string;
MyINI: TINIFile; // TINIFile objektet
PathToINIFile: String;

implementation
{$R *.dfm}

procedure TfmFontOpsestning.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TfmFontOpsestning.FormCreate(Sender: TObject);
begin
Edit1.Clear;
Edit2.Clear;
Edit4.Clear;

PathToINIFile := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0)))+'Settings.ini';
MyINI := TINIFile.Create(PathToINIFile);

  If Not FileExists(MyINI.FileName) Then
  Begin
      MessageDlg( 'Kan ikke finde opsætningsfilen: ' +  #13#10 +
              UpperCase( MyINI.FileName ) + #13#10
              +'Oprette nu:'+ #13#10
              +UpperCase(MyINI.FileName ),
              mtError, [mbOk], 0 );
    //IniFileError := True;
end;

MyINI.WriteString('Sektionen', 'Bibliotek', MyINI.FileName);

{Ved opstart af programmet hentes følgende:}

{FontName, FontSize, FontStyle og FontColor}
Edit1.Text := MyINI.ReadString('Sektionen', 'FontName', 'Ikke fundet');
Edit1.Font.Name:= Edit1.Text;

{Font Size}
Edit2.Text:= IntToStr(MyINI.ReadInteger('Sektionen', 'FontSize', 10));
Edit2.Font.Size:= Strtoint(Edit2.Text);

{Font Color}
Edit4.Text := MyINI.ReadString('Sektionen', 'FontColor', 'Ikke fundet');
Edit4.Font.Color:= StringToColor(Edit4.Text);

{Læser fra ini'en. 'Ikke fundet' kommer kun hvis der ikke er nogen værdi i undernøglen}
Label4.Caption := 'Af: '+ MyINI.ReadString('Sektionen', 'Bibliotek', 'Værdi mangler');

Label5.Caption:= 'Sidst opdateret den: ' + MyINI.ReadString('Sektionen', 'Dato','');
Label6.Caption:= 'Kl: ' + MyINI.ReadString('Sektionen', 'Kl','');

MyINI.Free;
end;

procedure TfmFontOpsestning.btnFontDialogClick(Sender: TObject);
begin
FontDialog1.Execute;
FontName  := FontDialog1.Font.Name;
FontSize  := FontDialog1.Font.Size;
FontColor := ColorToString(FontDialog1.Font.Color);

MyINI := TINIFile.Create(PathToINIFile);

{Font Name}
MyINI.WriteString('Sektionen', 'FontName', FontName);
Edit1.Text := MyINI.ReadString('Sektionen', 'FontName', 'Ikke fundet');
Edit1.Font.Name:= Edit1.Text;

{Font Size}
MyINI.WriteInteger('Sektionen', 'FontSize', FontSize);
Edit2.Text:= IntToStr(MyINI.ReadInteger('Sektionen', 'FontSize', 10));
Edit2.Font.Size:= Strtoint(Edit2.Text);

{Font Color}
MyINI.WriteString('Sektionen', 'FontColor', FontColor );
Edit4.Text := MyINI.ReadString('Sektionen', 'FontColor', 'Ikke fundet');
Edit4.Font.Color:= StringToColor(Edit4.Text);

MyINI.WriteBool('Sektionen', 'Bibliotek', True);
MyINI.WriteString('Sektionen','Bibliotek',MyINI.FileName);
MyINI.WriteDate('Sektionen', 'Dato', Date);
MyINI.WriteTime('Sektionen', 'Kl', time);

MyINI.Free;
end;

Med venlig hilsen
Monie Jacobsen
Avatar billede dkn Nybegynder
14. februar 2004 - 18:01 #1
{Font Color}
MyINI.WriteString('Sektionen', 'FontColor', FontColor );
Edit4.Text := MyINI.ReadString('Sektionen', 'FontColor', 'Ikke fundet');
Edit4.Font.Color:= StringToColor(Edit4.Text);


default value skal være en integer
Avatar billede monie Nybegynder
14. februar 2004 - 18:03 #2
Hvordan gørres dette? Har sel prøvet en del.
Vil du indskrive et eksempel jeg kan prøve med?
Avatar billede nca Juniormester
14. februar 2004 - 18:05 #3
Jeg tror fejlen ligger i denne linie:

1)Edit4.Text := MyINI.ReadString('Sektionen', 'FontColor', 'Ikke fundet');
2)Edit4.Font.Color:= StringToColor(Edit4.Text);

Hvis linie 1 ikke kan finde FontColor returneres 'Ikke fundet'
Linie 2 skal så forsøge at oversætte dette og giver fejl.
Prøv at erstatte 'Ikke fundet' med 0
Avatar billede dkn Nybegynder
14. februar 2004 - 18:07 #4
'Ikke fundet' er den default værdi som variablen skal antage hvis den ikke bliver fundet i ini filen.

hvis den ikke finder "FontColor", vil den skrive "Ikke fundet" i edit4, som derefter skal conventeres til en farve med StringToColor.

tror da det er der fejlen ligger, har kun lige kigget hurtig på det.
Avatar billede monie Nybegynder
14. februar 2004 - 18:14 #5
Men hvordan gøres det i min tekstkoder?
Avatar billede monie Nybegynder
14. februar 2004 - 18:17 #6
Til nca
Har prøvet:Edit4.Text := MyINI.ReadString('Sektionen', 'FontColor', '0');
men uden held.
Avatar billede dkn Nybegynder
14. februar 2004 - 18:23 #7
husk at rette den med StringToColor både i opstart af programmet og når der vælges farve.
Avatar billede monie Nybegynder
14. februar 2004 - 18:46 #8
Jeg kan ikke arbejde mere med problemmet i aften.
Men hvis du vil hjælpe, vil jeg blive meget glad, hvis du vil retigere mine koder
og sende dem til mjs@nypost.dk
Med venlig hilsen
Monie Jacobsen
Avatar billede nca Juniormester
14. februar 2004 - 18:50 #9
Har sendt rettet kode
Avatar billede monie Nybegynder
15. februar 2004 - 07:44 #10
Håber jeg gøre dette rigtigt.
For en stor tak for hjælpen.
Har forsøgt at tildele point således:
dkn fik 50 point
nca fik 50 point

Hvis ikke i har fået point, så er det forde jeg gør det forkert.
Så giv venligs besked og fortælle hvordan dette skal gøres.

Med venlig hilsen
Monie Jacobsen
Avatar billede monie Nybegynder
15. februar 2004 - 07:46 #11
Undskyld 30 point hver
Avatar billede nca Juniormester
15. februar 2004 - 09:53 #12
Der er ikke kommet point endnu.
Jeg kan ikke huske præcist hvordan man gør, når der er flere, der skal ha' point.
Et eller andet med at markere én af gangen og fortælle hvor mange point vedkommende skal ha'.
Avatar billede hrc Mester
15. februar 2004 - 18:42 #13
Jeg kiggede også lidt på din kode og for' selv til pennen for at lave nedenstående variant af dit testprogram.

Kan dog ikke afholde mig fra at stille noge spg. og komme med nogle kommentarer:

1. Hvorfor bruge ini-filer? Registreringsdatabasen blev opfundet før 95' (fandtes endda i win 3.11) og eneste grund til den er her er for bagud kompatibilitet (jeg vover pelsen igen ;-)). Den er ikke et sværere at bruge.

2. Du bør bruge Try-finally så du ikke har en TIniFile hængende hvis noget går ned - sådan som dit testprogram gør det.

3. Du bør undgå globale variable såsom FontName, FontSize osv. VÆK MED DEM!!! Flyt dem ind i funktionerne eller placér dem under private-sektionen på din form.

4. Koden er ineffektiv (se linierne):

    MyINI.WriteInteger('Sektionen', 'FontSize', FontSize);
    Edit2.Text:= IntToStr(MyINI.ReadInteger('Sektionen', 'FontSize', 10));

resulterer i, at værdien skrives, filen lukkes fordi den læses sekventielt / åbnes, værdien læses igen. Det kan godt være du reddes af, at den læser hele filen ind i hukommelsen, men det er stadig ineffektiv kodning.

5. Du bør overveje at bruge ReadSection i stedet for at læse værdierne een efter een. Igen optimerer det programmet.

6. Giv komponenterne fornuftige nave. Jeg bruger eFontName i stedet for Edit1 (e'et indikerer at det er en TEdit)

7. Brug fornuftige defaultværdier hvis tingene ikke findes. Sæt fonten til Courier, ikke 'Ikke fundet'.

Du må ikke tage kommentarerne som hug' men som de råd de er. Jeg forsøger altid at præge nye Delphi-programmører inden de får for mange unoder, men husk: Det er råd, ikke absolutte sandheder!

Min variant ser sådan ud:

procedure TfrmSub.FormCreate(Sender: TObject);
begin
  // Sætter filnavnet OnCreate. Bemærk f'et der fortæller at variablen er
  // defineret i den private del af TfrmSub
  fIniFileName := IncludeTrailingBackslash(
                    ExtractFilePath(ParamStr(0)))+'Settings.ini';
end;

procedure TfrmSub.Load(const aFileName : string);
begin
  eFontName.Clear;
  eFontSize.Clear;
  eFontColor.Clear;

  if not FileExists(aFileName) then begin
    MessageDlg(
      format('Filen %s er ikke fundet.'#13#10'Oprettes!',
            [UpperCase( aFileName)]),
    mtError, [mbOk], 0);

    lWritten.Caption := 'n/a'; // Put default values here

    exit; // Bail out!
  end; // if

  with TINIFile.Create(aFileName) do
    try
      {FontName, FontSize, FontStyle og FontColor}
      eFontName.Text := ReadString('Sektionen', 'FontName', 'Courier');
      eFontName.Font.Name:= eFontName.Text;

      {Font Size}
      eFontSize.Text:= IntToStr(ReadInteger('Sektionen', 'FontSize', 10));
      eFontSize.Font.Size:= Strtoint(eFontSize.Text);

      {Font Color}
      eFontColor.Text := ReadString('Sektionen', 'FontColor', ColorToString(clRed));
      eFontColor.Font.Color:= StringToColor(eFontColor.Text);

      lWritten.Caption:= 'Opdateret den: ' +
                DateTimeToStr(ReadDateTime('Sektionen', 'Written',0));
    finally
      Free;
    end; // try
end;

procedure TfrmSub.SetSave(const aFileName : string);
begin
  if not FontDialog1.Execute then
    exit;

  with TINIFile.Create(aFileName) do
    try
      {Font Name}
      WriteString('Sektionen', 'FontName', FontDialog1.Font.Name);
      eFontName.Text := FontDialog1.Font.Name;
      eFontName.Font.Name:= FontDialog1.Font.Name;

      {Font Size}
      WriteInteger('Sektionen', 'FontSize', FontDialog1.Font.Size);
      eFontSize.Text:= IntToStr(FontDialog1.Font.Size);
      eFontSize.Font.Size:= FontDialog1.Font.Size;

      {Font Color}
      WriteString('Sektionen', 'FontColor', ColorToString(FontDialog1.Font.Color));
      eFontColor.Text := ColorToString(FontDialog1.Font.Color);
      eFontColor.Font.Color:= FontDialog1.Font.Color;

      WriteDateTime('Sektionen', 'Written', now);
    finally
      Free; // ini-file
    end; // try
end;

procedure TfrmSub.btnLoadClick(Sender: TObject);
begin
  Load(fIniFileName);
end;

procedure TfrmSub.btnSaveClick(Sender: TObject);
begin
  SetSave(fIniFileName);
end;

Held og lykke med programmeringen og med din pointsgivning.
Avatar billede hrc Mester
15. februar 2004 - 19:05 #14
Monie: Du er efterhånden ved at have nogle points ude at svømme. Hvis nca og dkn har fået sine points i det andet indlæg du har i eksperten, så kan du selv svare på det - og så nuppe alle pointsene.
Avatar billede nca Juniormester
15. februar 2004 - 21:29 #15
>>hrc
Microsofts seneste anbefalinger går på, at programmerne gemmer deres brugerdata i en ini-fil i stedet for at bruge registreringsdatabasen.
Jeg ved godt det lyder som et tilbageskridt, men sådan forholder det sig faktisk.
Iøvrigt kan jeg tilslutte mig dine øvrige kommentarer.
Avatar billede hrc Mester
15. februar 2004 - 21:44 #16
Det var dælens! Gør de virkelig? Ja, ja, det kan jo være at tågen er lettet lidt i Redmond, Seattle. Troede ellers at den var beregenet til at gemme position, størrelse og sidst indtastede værdier.
Avatar billede monie Nybegynder
16. februar 2004 - 11:24 #17
Til hrc
Lige et øjeblik!
Jeg er ny her på Eksperten, og må selvfølgelige gøre mine erfaringer på godt og ondt.
Men allerhelt ønsker jeg kun, at gører det bedste.
Du har lavet et meget, meget udførelige og flot beskrivelse som jeg kan lærer meget af.Tak
Med en sådan beskrivelse vil jeg meget gerne give 60 point for.
Kan du ikke lige sig hvordan jeg kan gører det. Evt opret et spørgsmål, med et enkelt forspørgelse.
Med venlig hilsen
Monie Jacobsen
Avatar billede monie Nybegynder
16. februar 2004 - 12:40 #18
Til hrc

Har arbejdet med dit forslag.
Men der gå lidt kluder i det.
F.eks.
1: procedure TfrmSub.Load(const aFileName : string);
  Har forsøgt i Type procedure Load(const aFileName : string);
  at oprette proceduren med "Complete class at cursor" men uden held.
2: SetSave(fIniFileName); Er SetSave ikke forkert.

Kan jeg få tilsendt din Unit ?

Min E-mail: mjs@nypost.dk
Med venlig hilsen
Monie Jacobsen
Avatar billede hrc Mester
16. februar 2004 - 12:57 #19
Hej Monie. Jeg så godt at du var nyinstalleret (;-), velkommen til. Jeg selv blev først opmærksom på stedet i efteråret 2003 så jeg er også ret våd bag ørerne (det er anden gang jeg blamerer mig med bedreviden i forb. med "bagud kompatibilitet").

Jeg har lige en tilføjelse til punkt 6 i ovenstående liste. Se evt. et forsøg på en navngivningskonvension: http://delphi.about.com/library/bldnc.htm

delphi.about.com kan i øvrigt anbefales varmt.

Har lidt svært ved at acceptere, at du vil give points for mit indlæg - det kan sagtens blive bedre. Det vigtigste var, at jeg fik min kæphest om try-finally og try-except frem. Det er meget praktiske konstruktioner og programmerne bliver meget bedre når de bruges korrekt.

... men jeg kan fristes (;-) så vedlægger jeg lige nedenstående eksempel på brug af ReadSectionValues (ReadSection returnerer kun navnene, ikke værdierne og er i praksis ret ubrugelig) samt hvordan de let kan indlæses i den smarte ValueListEditor.

procedure TfrmMain.Load(const aIniFileName : string);
begin
  // Nogle kalder det et hack at bruge With på denne måde. Jeg opretter TIniFile
  // via en with-konstruktion og pakker jeg den ind i en try-finally som sikrer,
  // at den frigives igen. Jeg synes selv det er elegant, mens andre synes det
  // mindsker læsbarheden.

  with TIniFile.Create(aIniFileName) do
    try
      ReadSectionValues('Font',ValueListEditor1.Strings);
    finally
      Free;
    end; // try
end;

Skal du bruge værdierne ser det sådan ud:

procedure Load(const aIniFileName : string);
begin
  StringList := TStringList.Create;
  Ini := TIniFile.Create(aIniFileName);
  try
    Ini.ReadSectionValues('Font',StringList);
    eFontName.Text := StringList.Values[Name];
    eFontSize.Text := StringList.Values[Size];
    eFontColor.Text := StringList.Values[Color];
  finally
    Ini.Free;
    StringList.Free;
  end; // try
end;
Avatar billede hrc Mester
16. februar 2004 - 13:05 #20
ad. 1. Er det det her du mangler?

type
  TfrmSub = class(TForm)
  private
    procedure Load(const aFileName : string); // mangler du denne linie?
    procedure SetSave(const aFileName : string); // og denne?
  end;

ad. 2. Det synes jeg ikke - jeg ændrer jo værdierne inden jeg gemmer dem.

Pas på med at angive "fungerende" emails i offentlige fora. Skriv evt. mjsSnabelAnypost.dk i stedet - så narrer man mange spammere.
Avatar billede hrc Mester
16. februar 2004 - 13:21 #21
Lige en rettelse:

    eFontName.Text := StringList.Values['Name'];
    eFontSize.Text := StringList.Values['Size'];
    eFontColor.Text := StringList.Values['Color'];

Bemærk i øvrigt at den vist er case-sensitiv.
Avatar billede monie Nybegynder
16. februar 2004 - 13:23 #22
Til hrc
Vil du prøve, at sende mig dit Unit for programeksemplet eller måske hele programmet.

Jeg prøver, at se om jeg kan give dig nogen point.
Se lige om du for nogen.

Ellers oprette jeg et spørgsmå, der er rette til dig, så du kan få de fortjente point.
Med ven lig hilsen
Monie Jacobsen
E-mail mjs at nypost dot dk
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester