Link to home
Start Free TrialLog in
Avatar of Magneto_Mystique
Magneto_Mystique

asked on

Delphi Help

I am new to Delphi.  I have to make changes to a Delphi program which creates an ini and clm files when it is in use.  The problem now is that the application is to be placed on a Citrix server where it will be at one location (one exe at one location) and many users accessing the same app at the same location.  Because the app creates an ini and clm files when in use, concerns are raised about having mulitple users accessing the same exe at the same time.  In fact error messages like "Error writing to XXX.ini file" are popping up.  

I was told then to direct the output of these ini and clm files to a local directory specific to each user's machine.  Currently, the ini and clm files are created in the same directory in which the exe is stored.  However, I don't know how to do it or how to start it.  Any ideas?  I included the method below which creates the ini and clm files.

procedure TfrmEsnview.FormCreate(Sender: TObject);
var
   i: integer;
begin
   CalledFromTargys := False;
   Application.OnMessage := AppMessage;

   bDebug := False; // MM

   if not Assigned(EsnViewDataModule) then
      Application.CreateForm(TEsnViewDataModule, EsnViewDataModule);

   Top := ini.ReadInteger(cfgEVew, 'Top', 100);
   Left := ini.ReadInteger(cfgEVew, 'Left', 100);
   Width := ini.ReadInteger(cfgEVew, 'Width', 753);
   Height := ini.ReadInteger(cfgEVew, 'Height', 550);

   dbGrid6.Width := ini.ReadInteger(cfgEVew, 'dbGrid6Width', 600);

   clmFile1 := ExtractFilePath(Application.ExeName) + cfgEVew + '1.clm';
   clmFile2 := ExtractFilePath(Application.ExeName) + cfgEVew + '2.clm';
   clmFile3 := ExtractFilePath(Application.ExeName) + cfgEVew + '3.clm';
   clmFile4 := ExtractFilePath(Application.ExeName) + cfgEVew + '4.clm';
   clmFile5 := ExtractFilePath(Application.ExeName) + cfgEVew + '5.clm';
   clmFile6 := ExtractFilePath(Application.ExeName) + cfgEVew + '6.clm';
   if FileExists(clmFile1) then
      begin // Status
         dbGrid1.Columns.LoadFromFile(clmFile1);
      end;
   if FileExists(clmFile1) then
      begin // Channel Information
         dbGrid2.Columns.LoadFromFile(clmFile2);
      end;
   if FileExists(clmFile3) then
      begin // Attached Cards
         dbGrid3.Columns.LoadFromFile(clmFile3);
      end;
   if FileExists(clmFile4) then
      begin // Attached Cards (History)
         dbGrid4.Columns.LoadFromFile(clmFile4);
      end;
   if FileExists(clmFile5) then
      begin // PRL
         dbGrid5.Columns.LoadFromFile(clmFile5);
      end;
   if FileExists(clmFile6) then
      begin // Warranty
         dbGrid6.Columns.LoadFromFile(clmFile6);
      end;

   sgActivity.Cells[colActSerialNo, 0] := 'Serial Number';
   sgActivity.Cells[colActPwrOn, 0] := '1st Power On';
   sgActivity.Cells[colActPwrLast, 0] := 'Last Power On';
   sgActivity.Cells[colActPwrTotal, 0] := 'Total Power On';
   for i := 0 to sgActivity.ColCount - 1 do
      begin
         sgActivity.ColWidths[i] :=
            ini.ReadInteger(cfgEVew, 'sgActivityCol' + zIntToStr(i, 3),
            100);
      end;
end;
Avatar of shaneholmes
shaneholmes

SO you are saying the application is now on a server on the network, and users are running it from there, and you want it to cteate the INI file and CLM file on there local machine when they run the app on the server?

I dont hink im reading this correctly!

sholmes
Avatar of TheRealLoki
many users accessing the same exe is ok.
you haven't actually shown the ini file creation in your code
if you want to use a different ini or clm file for each user, then perhaps you could include the user's name in the file e.g.
clmFile1 := ExtractFilePath(Application.ExeName) + cfgEVew + fUsername + '_1.clm';
clmFile2 := ExtractFilePath(Application.ExeName) + cfgEVew + fUsername + '_2.clm';
etc.
so it actually looks like
bob_1.clm
bob_2.clm
sam_1.clm
sam_2.clm

you mention the error says xxx.ini  but i see no .ini in your example code. is the problem elsewhere?
you should access ini files like this

with TIniFile.Create('myname.ini') do
try
     i := readinteger(section, ident, default);
finally
    free;
end;
that way you can be sure you are not leaving too many files open when not in use
I get the impression that you probably need 2 sets of data.

The first is the location of your datafiles which are persistent settings.

Leave these as being read from the central ini file

The 2nd set of data is local to the user
i.e. the size and layout of the form and sort order etc

if this is the case then you could add these to the registry

using something like

-----------------put this in the form create to load settings-------------------

procedure TfrmMain.FormCreate(Sender: TObject);
var
      lReg:    TRegistry;
begin
      lReg:=tRegistry.Create;
      try
            lReg.RootKey := HKEY_CURRENT_USER;
            if lReg.OpenKeyReadOnly('\Software\ESNView') then
            begin
                  if lReg.ValueExists('Top') then
                        Top:=lReg.ReadInteger('Top');
                  if lReg.ValueExists('Left') then
                        Left:=lReg.ReadInteger('Left');
                  if lReg.ValueExists('Height') then
                        Height:=lReg.ReadInteger('Height');
                  if lReg.ValueExists('SortColumn') then
                        FColumnSort:=lReg.ReadInteger('SortColumn');
                  if lReg.ValueExists('SortAscending') then
                        FSortAscending:=lReg.ReadBool('SortAscending');
                  if lReg.ValueExists('NameOrder') then
                        FNameSort:=lReg.ReadBool('NameOrder');
            end;
      finally
            lReg.CloseKey;
            lReg.Free;
      end;

end

-----------------put this in the form close to save settings-------------------

procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
//saves the position, size and settings
var
      lReg:            TRegistry;
  lPl : TWindowPlacement;
  lR: TRect;
begin
      try
            LockWindowUpdate(Handle);
    lPl.Length := SizeOf(TWindowPlacement);
    GetWindowPlacement(Self.Handle, @lPl);
    lR := lPl.rcNormalPosition;
            lReg:=tRegistry.Create;
            try
                  lReg.RootKey := HKEY_CURRENT_USER;
                  if lReg.OpenKey('\Software\EsnView',true) then
                  begin
        lReg.WriteInteger('Left', lR.Left);
        lReg.WriteInteger('Top', lR.Top);
        lReg.WriteInteger('Height', lR.Bottom-lR.Top);
        lReg.WriteBool('NameOrder', FNameSort);
        lReg.WriteBool('SortAscending', FSortAscending);
        lReg.WriteInteger('SortColumn', FColumnSort);
                  end;
            finally
                  lReg.CloseKey;
                  lReg.Free;
            end;
      finally
            LockWindowUpdate(0);
      end;
end;

This way local settings will not interfere with the central information

regards
keeping the same concept you have... something like this:

procedure TForm1.FormCreate(Sender: TObject);
var
   i: integer;
   BaseFileName, BasePath:string;
  procedure LoadFile(const FileName:string; dbGrid:TDBGrid);
  begin
    if (FileExists(FileName)) then
      dbGrid.Columns.LoadFromFile(FileName)
  end;
begin
   CalledFromTargys := False;
   Application.OnMessage := AppMessage;

   bDebug := False; // MM

   if not Assigned(EsnViewDataModule) then
      Application.CreateForm(TEsnViewDataModule, EsnViewDataModule);

   Top := ini.ReadInteger(cfgEVew, 'Top', 100);
   Left := ini.ReadInteger(cfgEVew, 'Left', 100);
   Width := ini.ReadInteger(cfgEVew, 'Width', 753);
   Height := ini.ReadInteger(cfgEVew, 'Height', 550);

   dbGrid6.Width := ini.ReadInteger(cfgEVew, 'dbGrid6Width', 600);

   BasePath:=IncludeTrailingBackslash(ini.ReadString('Config', 'BasePath', 'c:\')); //default to c:\

   BaseFileName:=BasePath+cfgEVew;

   clmFile1 := BaseFileName + '1.clm';
   clmFile2 := BaseFileName + cfgEVew + '2.clm';
   clmFile3 := BaseFileName + cfgEVew + '3.clm';
   clmFile4 := BaseFileName + cfgEVew + '4.clm';
   clmFile5 := BaseFileName + cfgEVew + '5.clm';
   clmFile6 := BaseFileName + cfgEVew + '6.clm';
   LoadFile(clmFile1, dbGrid1);
   LoadFile(clmFile2, dbGrid2);
   LoadFile(clmFile3, dbGrid3);
   LoadFile(clmFile4, dbGrid4);
   LoadFile(clmFile5, dbGrid5);
   LoadFile(clmFile6, dbGrid6);

   sgActivity.Cells[colActSerialNo, 0] := 'Serial Number';
   sgActivity.Cells[colActPwrOn, 0] := '1st Power On';
   sgActivity.Cells[colActPwrLast, 0] := 'Last Power On';
   sgActivity.Cells[colActPwrTotal, 0] := 'Total Power On';
   for i := 0 to sgActivity.ColCount - 1 do
      begin
         sgActivity.ColWidths[i] :=
            ini.ReadInteger(cfgEVew, 'sgActivityCol' + zIntToStr(i, 3),
            100);
      end;
end;
Avatar of Magneto_Mystique

ASKER

I tried changing the code like above.  I can successfully direct the path of the clm files to C:.  The ini file is created in the uGlobal.  I would like to direct it to the same path as the clm files.  I tried to change it like the below but it doesn't work.  Why?

var
    ini: TIniFile;
    semsfile, semsfilepath: string;

const
    ver = '8.30';

    cfgMain = 'Main';              
    cfgStat = 'CardStatus';
    cfgView = 'CardView';
    cfgEVew = 'ESNViewer';
    cfgFirmBrow = 'FirmBrow';
    cfgLostStolen = 'LostStolen';
    cfgSVew = 'RIM Software Viewer';
                                           
    techPCS     = 'PCS';
    techIDEN    = 'IDEN';
    techSIM     = 'SIM';
    techANALOG  = 'ANALOG';
    techPAGER   = 'PAGER';
    techCDPD    = 'MODEM';

    stBES = 'BES Software';
    stLicense = 'SOFTWARE LICENSE';

    SCHEMA = '';

implementation

initialization
    semsfilepath := IncludeTrailingBackslash(ini.ReadString('Config', 'semsfilepath', 'c:\Example')); //default to c

    semsfile:= semsfilepath + cfgEVew;

    ini := TIniFile.Create(semsfile + 'SEMS.ini');

finalization
    ini.Free;

end.
ASKER CERTIFIED SOLUTION
Avatar of Kyle Foster
Kyle Foster
Flag of United States of America 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
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.

I will leave the following recommendation for this question in the Cleanup topic area:
   Accept: kfoster11 {http:#15810258}

Any objections should be posted here in the next 4 days. After that time, the question will be closed.

cwwkie
EE Cleanup Volunteer