Link to home
Start Free TrialLog in
Avatar of pr2501
pr2501

asked on

Ini file complication

In the code below i have error :
[Pascal Error] openMap.pas(564): E2003 Undeclared identifier: 'WriteInteger'
for:
WriteInteger(Self.Name, cmpLabel.Name + ' Top', integer(TLabel(cmpLabel).Top));

You may see that am recording information abot  Tshape in first "try" section.
And if i work only with this section everything is ok. But when i add second "try" for Tlabel recording problems starts.

I believe i will have same problem for reading from ini file. But help me pleas at first   with storing.
       
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  cmp,cmplabel: tcomponent;
  i,j: integer;
  Fname:string;
begin
  with TINIFile.Create(ExtractFilePath(Application.Exename) + 'yourini.ini')  do

  try
      
      i := 1;
      cmp := FindComponent('Shape' + IntToStr(i));
    while cmp <> nil do
    begin
       WriteInteger(Self.Name, cmp.Name + ' Brush Color', integer(TShape(cmp).Brush.Color));
;………………
    
       i := i + 1;
       cmp := FindComponent('Shape' + IntToStr(i));
       if cmp = nil then
         WriteInteger(Self.Name, 'Shapes', i-1);
       end;
   finally
    free;
    end;

  /////////77
  ///
   try
  j := 1;
    cmpLabel := FindComponent('Label' + IntToStr(j));
    while cmpLabel <> nil do
    begin
  //     WriteInteger(Self.Name, cmpLabel.Name + ' Height', integer(TLabel(cmpLabel).Height));
       WriteInteger(Self.Name, cmpLabel.Name + ' Top', integer(TLabel(cmpLabel).Top));
       WriteInteger(Self.Name, cmpLabel.Name + ' Left', integer(TLabel(cmpLabel).Left));

         j := j + 1;
       cmpLabel := FindComponent('Label' + IntToStr(j));
       if cmplabel = nil then
         WriteInteger(Self.Name, 'Label', j-1);
    end;
  ///  /////77
  IniFile.Free;
   finally
   free;
 end ;
end;

Open in new window

Avatar of EmuL8_sw
EmuL8_sw
Flag of South Africa image

I think what would work better is if you declare the INI file as a VAR

Please see my example I use for all my programs
var
FrntIni: TIniFile;
begin
FrntIni := TIniFile.Create(Path + 'Config.ini');
      try
        FrntIni.WriteInteger('Timer', 'Interval', timer1.Interval);

      finally
        FrntIni.Free;
      end;
end

Open in new window

Maybe you should not use the WITH statement, but instead store the instance of the TIniFile you create in a local variable "MyIniFile" and use that one instead.

So  MyIniFile.WriteInteger etc.
Avatar of Geert G
the with may get resolved wrongly
WriteInteger may be found in a other unit as standalone procedure with different parameters

ah no ... you have freed you inifile ...

below the second try !

see where i altered and then stopped ?
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  cmp,cmplabel: tcomponent;
  i,j: integer;
  Fname:string;
  F: TIniFile;
begin
  F := TINIFile.Create(ExtractFilePath(Application.Exename) + 'yourini.ini');
  try
    i := 1;
    cmp := FindComponent('Shape' + IntToStr(i));
    while cmp <> nil do
    begin
       F.WriteInteger(Self.Name, cmp.Name + ' Brush Color', integer(TShape(cmp).Brush.Color));
       i := i + 1;
       cmp := FindComponent('Shape' + IntToStr(i));
       if cmp = nil then
         F.WriteInteger(Self.Name, 'Shapes', i-1);
     end;
  finally
    F.free;
  end;

  /////////77
  ///
  try
    j := 1;
    cmpLabel := FindComponent('Label' + IntToStr(j));
    while cmpLabel <> nil do
    begin
  //     WriteInteger(Self.Name, cmpLabel.Name + ' Height', integer(TLabel(cmpLabel).Height));
       WriteInteger(Self.Name, cmpLabel.Name + ' Top', integer(TLabel(cmpLabel).Top));
       WriteInteger(Self.Name, cmpLabel.Name + ' Left', integer(TLabel(cmpLabel).Left));

         j := j + 1;
       cmpLabel := FindComponent('Label' + IntToStr(j));
       if cmplabel = nil then
         WriteInteger(Self.Name, 'Label', j-1);
    end;
  ///  /////77
  IniFile.Free;
   finally
   free;
 end ;
end;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Geert G
Geert G
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
To fix your problem I suspect simply enclosing your with statement with begin and end statements will solve it.
Avatar of pr2501
pr2501

ASKER

The Geert_Gruwez resolutioon is ok. Maybe PierreC proposition is corect. But now i' m working (as i mentioned at start)  to also resolve the same problem with reading.  So... just a moment.
well i think you have a problem in your with the last free

    end;
    ///  /////77
    IniFile.Free;
  finally
    free; // this free is for the form since there is no longer a with used for this ...
  end ;
end;


and this free is for the unit , but i have my doubts about this doing anything :)

   IniFile.Free;
Using an INI file in this case may not be the best solution. You would be better of using XML.
However here is the code to read and write the properties.
I differentiate the sections for storing labels and Shapes
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  SaveProperties;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  ReadProperties;
end;

procedure TForm1.ReadProperties;
var
  Comp: TComponent;
  I: integer;
  ComponentName, CurrentSection, CompProperty:string;
  F: TIniFile;
  List: TStringList;
  function ExtractShapeName(const AEntry: string): string;
  var
    J: Integer;
  begin
    Result := '';
    if Pos('Shape', AEntry) > 0 then
    begin
      J := Pos(' ', AEntry);
      if J > 0 then
        Result := Copy(AEntry, 1, J-1);
    end;
  end;
  function ExtractLabelName(const AEntry: string; out AProperty: string): string;
  var
    J: Integer;
  begin
    Result := '';
    AProperty := '';
    if Pos('Label', AEntry) > 0 then
    begin
      J := Pos(' ', AEntry);
      if J > 0 then
      begin
        Result := Copy(AEntry, 1, J-1);
        if Pos('Top', AEntry) > 0 then
          AProperty := 'Top'
        else if Pos('Left', AEntry) > 0 then
          AProperty := 'Left'
      end;
    end;
  end;
begin
  F := TINIFile.Create(ExtractFilePath(Application.Exename) + 'yourini.ini');
  try
    List := TStringList.Create;
    try
      CurrentSection := 'SHAPE';
      F.ReadSection(CurrentSection, List);
      for I := 0 to List.Count - 1 do
      begin
        ComponentName := ExtractShapeName(List[I]);
        Comp := FindComponent(ComponentName);
        if Assigned(Comp) then
          TShape(Comp).Brush.Color := F.ReadInteger(CurrentSection, List[I], TShape(Comp).Brush.Color);
      end;

      List.Clear;
      CurrentSection := 'LABEL';
      F.ReadSection(CurrentSection, List);
      for I := 0 to List.Count - 1 do
      begin
        ComponentName := ExtractLabelName(List[I], CompProperty);
        Comp := FindComponent(ComponentName);
        if Assigned(Comp) then
        begin
          if CompProperty = 'Top' then
             TLabel(Comp).Top := F.ReadInteger(CurrentSection, List[I], TLabel(Comp).Top)
          else if CompProperty = 'Left' then
             TLabel(Comp).Left := F.ReadInteger(CurrentSection, List[I], TLabel(Comp).Top);
        end;
      end;
    finally
      FreeAndNil(List);
    end;
  finally
    FreeAndNil(F);
  end;
end;

procedure TForm1.SaveProperties;
var
  Comp: tcomponent;
  I: integer;
  Fname:string;
  F: TIniFile;
  CurrentSection: string;
begin
  F := TINIFile.Create(ExtractFilePath(Application.Exename) + 'yourini.ini');
  try
    CurrentSection := 'SHAPE';

    I := 1;
    Comp := FindComponent('Shape' + IntToStr(I));
    while Comp <> nil do
    begin
       F.WriteInteger(CurrentSection, Comp.Name + ' Brush Color', Integer(TShape(Comp).Brush.Color));
       Inc(I);
       Comp := FindComponent('Shape' + IntToStr(I));
     end;

    CurrentSection := 'LABEL';

    I := 1;
    Comp := FindComponent('Label' + IntToStr(I));
    while Comp <> nil do
    begin
       F.WriteInteger(CurrentSection, Comp.Name + ' Top', Integer(TLabel(Comp).Top));
       F.WriteInteger(CurrentSection, Comp.Name + ' Left', Integer(TLabel(Comp).Left));

       Inc(I);
       Comp := FindComponent('Label' + IntToStr(I));
    end;
  finally
    FreeAndNil(F);
  end;
end;

Open in new window

Avatar of pr2501

ASKER

Am using code from proposition of Geert_Gruwez. Now i need also code to modificate my code below to read data about TLabel.
Sorry i have tray but i can't do it by myself.
// get ini
procedure TForm1.FormCreate(Sender: TObject);
var
  cmp: TShape;
  i: integer;
  Fname:string;

begin  //1
  FShapeNumber := 0;
 with TINIFile.Create(ExtractFilePath(Application.Exename) + 'yourini.ini')do  begin //2
      try //3
       caption:= ReadString(Self.Name, 'Caption', Caption);
       LoadBackground( ReadString('_global_', 'bitmapfile', '' ) );
       pathstrBitmapFile:=  ReadString('_global_', 'bitmapfile', '' );
       n := ReadInteger(Self.Name, 'Shapes', 0);
       for i := 1 to n do
       begin  //4
       // if you use TShape as class, you only need to cast once
         cmp := TShape(FindComponent('Shape' + IntToStr(i)));
         if cmp = nil then
         begin //5
          cmp := TShape.Create(Self);
          cmp.Name := 'Shape' + IntToStr(I);
          cmp.Parent := Self;
          cmp.onMouseDown := ShapeMouseDown;
          cmp.onMouseMove := ShapeMouseMove;
          cmp.onMouseUp := ShapeMouseUp;
          cmp.Tag := FShapeNumber;
          inc(FShapeNumber);
          cmp.Brush.Color := TColor(ReadInteger(Self.Name, cmp.Name + ' Brush Color', integer(clGreen)));
          cmp.Width := ReadInteger(Self.Name, cmp.Name + ' Width', cmp.Width);
          cmp.Height := ReadInteger(Self.Name, cmp.Name + ' Height', cmp.Height);
          cmp.Top := ReadInteger(Self.Name, cmp.Name + ' Top', cmp.Top);
          cmp.Left := ReadInteger(Self.Name, cmp.Name + ' Left', cmp.Left);
          cmp.hint :=readString(Self.Name, cmp.Name + ' Hint',TShape(cmp).Hint);
          cmp.showhint :=readBool(Self.Name, cmp.Name + ' ShowHint',TShape(cmp).Showhint);
            end; //5
          end;  // 4
       finally
       free;
       end; //3
     Application.Showhint := true;
  end;  //2

end;  //1

Open in new window

you have trouble with the try begin and end
because you don't indent correctly
if you do the indenting correctly you don't need //1 //2 //3

and i never leave a free on it's own
i allways tell free explicitely what to free ... otherwise it may even free the form :)
procedure TForm1.FormCreate(Sender: TObject);
var
  cmp: TShape;
  i: integer;
  Fname: string;
  ini: TIniFile;
begin  
  FShapeNumber := 0;
  F := TINIFile.Create(ExtractFilePath(Application.Exename) + 'yourini.ini');
  with F do  
  try 
    caption:= ReadString(Self.Name, 'Caption', Caption);
    LoadBackground( ReadString('_global_', 'bitmapfile', '' ) );
    pathstrBitmapFile:=  ReadString('_global_', 'bitmapfile', '' );
    n := ReadInteger(Self.Name, 'Shapes', 0);
    for i := 1 to n do
    begin  
      // if you use TShape as class, you only need to cast once
      cmp := TShape(FindComponent('Shape' + IntToStr(i)));
      if cmp = nil then
      begin 
        cmp := TShape.Create(Self);
        cmp.Name := 'Shape' + IntToStr(I);
        cmp.Parent := Self;
        cmp.onMouseDown := ShapeMouseDown;
        cmp.onMouseMove := ShapeMouseMove;
        cmp.onMouseUp := ShapeMouseUp;
        cmp.Tag := FShapeNumber;
        inc(FShapeNumber);
      end;
      cmp.Brush.Color := TColor(ReadInteger(Self.Name, cmp.Name + ' Brush Color', integer(clGreen)));
      cmp.Width := ReadInteger(Self.Name, cmp.Name + ' Width', cmp.Width);
      cmp.Height := ReadInteger(Self.Name, cmp.Name + ' Height', cmp.Height);
      cmp.Top := ReadInteger(Self.Name, cmp.Name + ' Top', cmp.Top);
      cmp.Left := ReadInteger(Self.Name, cmp.Name + ' Left', cmp.Left);
      cmp.hint := readString(Self.Name, cmp.Name + ' Hint',TShape(cmp).Hint);
      cmp.showhint := readBool(Self.Name, cmp.Name + ' ShowHint',TShape(cmp).Showhint);
    end;  // for loop     
  finally
    F.free;
  end; 
  Application.Showhint := true;
end;

Open in new window