Ver Mensaje Individual
  #1  
Antiguo 12-07-2018
bucanero bucanero is offline
Miembro
 
Registrado: nov 2013
Ubicación: Almería, España
Posts: 208
Reputación: 11
bucanero Va camino a la fama
Crear una clase descendiente de TInifile

Hola a todos

Estoy intentando crear una clase descendiente de TIniFile, con la idea de tener una unidad para gestionar la configuración de laS aplicaciones de tal forma que si se le pasa alguna clase descendiente de un TINIFILE, trabaje con esta clase, en caso de no declara nada que trabaje con la clase general de TINIFile.

Este es el código para la unidad de configs.pas
Código Delphi [-]
unit configs;

interface

uses inifiles;

type
  TClassIniFile = class of TInifile;

var
  ClassIniFile: TClassIniFile = nil;
  IniFileName: string = 'c:\tmp\config.ini';


  function config: TIniFile;

implementation

uses Dialogs;

var
  IniFile:TInifile = Nil;

function config: TIniFile;
begin
  if not Assigned(IniFile) then begin
    if not Assigned(ClassIniFile) then begin
      //Si no hay definida una clase especifica se usa la clase generia de INIFILE
      IniFile := TiniFile.Create(IniFileName)
    end
    else begin
      // se usa la clase especifica
      IniFile := ClassIniFile.Create(IniFileName)
    end;
    // esto es solo en pruebas y es para mostrar que clase se esta utilizando
    MessageDlg(IniFile.ClassName, mtWarning, [mbOK], 0);
  end;
  Result := IniFile;
end;

initialization

finalization
  if assigned(IniFile) then
    IniFile.Free;
end.

Y la forma de utilizarlo en cualquier parte del programa:

Código Delphi [-]
uses configs;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  with config do
    WriteString('prueba', 'prueba', '123');
end;

y así es como redefino una nueva clase descendiente de TInifile
Código Delphi [-]
unit MyIniFiles;

interface

uses IniFiles;

type
  TMyIniFile = class(TIniFile)
  private
  public
    constructor Create(const FileName: string); overload;
  end;

implementation

uses dialogs, configs;

{ TMyIniFile }
constructor TMyIniFile.Create(const FileName: string);
begin
   // esto es solo en pruebas y es para mostrar si pasa por aqui
  MessageDlg('TMyIniFile.create', mtInformation, [mbOK], 0);
  inherited Create(FileName);
end;

initialization
  ClassIniFile := TMyIniFile;
end.


Y aquí es donde viene el problema, tal como esta todo esto declarado, el código del constructor de la clase descendiente (TMyIniFile.Create) no se ejecuta al crear la instancia del objeto desde la variable ClassIniFile y pasa directamente a ejecutar el constructor de la clase padre (TiniFile.create).

Por el contrario si en el procedimiento config lo pusiera de esta forma, entonces si que funciona perfectamente:
Código Delphi [-]
function config: TIniFile;
begin
  if not Assigned(IniFile) then begin
    if not Assigned(ClassIniFile) then
      //Si no hay definida una clase especifica se usa la clase generia de INIFILE
      IniFile := TiniFile.Create(IniFileName)
    else if (ClassIniFile = TMyIniFile) then
      // se usa la clase especifica
      IniFile := TMyIniFile.Create(IniFileName)
    else
      // se usa la clase especifica
      IniFile := ClassIniFile.Create(IniFileName);
    // esto es solo en pruebas y es para mostrar que clase se esta utilizando
    MessageDlg(IniFile.ClassName, mtWarning, [mbOK], 0);
  end;

  Result := IniFile;
end;

Pero de esta forma no quiero ponerlo, por que así estaría forzado a tener que añadir siempre en el uses de la unidad configs la unidad que contiene la clase descendiente, pudiendo estar unas veces incluida en el proyecto y otras veces no.

Me explico mas, mi idea es si en una determinada aplicación que utiliza la unidad CONFIGS le agrego la otra unidad con la clase descendiente, entonces esa aplicación usara esa clase descendiente para gestionar como y donde guardar la configuración, pero si en otra aplicación distinta que también usa la misma unidad CONFIGS, no tiene agregada ninguna unidad descendiente de TINIFILE, entonces se pretende que utilice la clase genérica de TINIFILE.

No se si alguien me puede arrojar luz sobre por que no se ejecuta la clase constructora descendiente al llamarla desde la variable que contiene la clase descendiente.

Gracias por vuestro tiempo
y saludos
Responder Con Cita