Ver Mensaje Individual
  #1  
Antiguo 25-11-2008
Khronos Khronos is offline
Miembro
 
Registrado: abr 2007
Posts: 298
Reputación: 18
Khronos Va por buen camino
Proyecto Wini

Hola, como sabéis en Windows con cuentas limitadas se producen errores la grabar la configuración en archivos ini, para evitar este problema en una tarde de aburrimiento se me ocurrió la idea de crear mi propio intérprete de estos archivos. Total que es una simple dll que no llega a los 60 kb y que es muy fácil de utilizar.

Además me gustaría compartir su código fuente con ustedes, no es gran cosa pero bueno

Utilizo la clase TStringList para operar con las cadenas de texto, junto con todo el "arsenal" de funciones que posee delphi para operar con cadenas de texto

Espero sus comentarios y sugerencias, espero que entre todos podamos mejorar este pequeño proyecto

Código Delphi [-]
library wini;

{**********************************************************
 *                  Windows Ini Files                     *
 *                   Autor: Khronos                       *
 *              email: tanisperez@gmail.com               *
 **********************************************************
 Puedes usar libremente esta librería sin ningún tipo de
 compromiso legal con el autor.
 **********************************************************
 **********************************************************
 *                      ~Khronos                          *
 **********************************************************
 **********************************************************
 **********************************************************}

uses
  Core in 'Core.pas';

{$R *.res}

end.


Código Delphi [-]
unit Core;

interface

uses Classes, SysUtils;

const
  WINI_FILE_CRETED                = $FFA1;
  WINI_FILE_LOADED                = $FFA2;
  WINI_NOT_REPAIRED               = $DD3;
  WINI_INI_REPAIRED               = $DD1;

  WINI_WRITE_ERROR_UNKNOWN        = $BF14;
  WINI_WRITE_SECTION_ADDED        = $BA7;
  WINI_WRITE_IDENTIFICATOR_ADDED  = $AA81;
  WINI_WRITE_VALUE_CHANGED        = $AA14;

  WINI_FREE_ERROR                 = $CC9;
  WINI_FREE_OK                    = $CC1;


type
  DWORD = LongWord;
  WINISections = record
      iStart, iEnd: integer;
  end;
  TWiniSections = WINISections;

var
  Ini: TStringList;
  WiniFileName: string;


function LocateSection(const Section: string; var IniSections: TWiniSections): boolean; stdcall;
function LocateId (index: integer): string; stdcall;
function LocateIdentificator(WiniSections: TWiniSections; const Identificator: string): integer; stdcall;
function LoadIniFile(const FileName: string): DWORD; stdcall;
function ReadStringIdentificator(index: integer): string; stdcall;
procedure SetStringValue(index: integer; value: string); stdcall;
function ReadIniString(const Section: string; const Identificator: string; const Default: string): string; stdcall;
function WriteIniString(const Section: string; const Identificator: string; const Value: string): DWORD; stdcall;
function FreeWini: DWORD; stdcall;


exports
  ReadIniString,
  LoadIniFile,
  WriteIniString,
  FreeWini;

implementation

//Function: LocateSection
//Esta función localiza donde empieza y donde acaba una sección. Devuelve
//false si no tiene éxito.
function LocateSection(const Section: string; var IniSections: TWiniSections): boolean;
var
i, u: integer;
str: string;
begin
result:= false;
  for i := 0 to Ini.Count - 1 do
      begin
        if Ini.Strings[i] = '[' + Section + ']' then
          begin
            result:= true;
            IniSections.iStart:= i + 1;
            for u := i + 1 to Ini.Count - 1 do
                begin
                  str:= Ini.Strings[u];
                  if (str[1] = '[') and (str[length(str)] = ']') then
                    begin
                      IniSections.iEnd:= u - 1;
                      break;
                    end;
                  if u = Ini.Count - 1 then IniSections.iEnd:= u;
                end;
          end;
      end;
end;


//Function: LocateId
//Función que sirve para obtener el nombre del identificador pasándole como
//parámetro una línea. Ejemplo: VideoCodec = ffdshow... obtendría el string VideoCodec
function LocateId (index: integer): string;
var
i:integer;
s: string;
begin
 result:= EmptyStr;
 i:=Pos('=', Ini.Strings[index]);
 s:=Copy(Ini.Strings[index], 1, i - 1);
 result:= Trim(s);
end;


//Function: LocateIdentificator
//Busca un identificador dentro de una sección.
function LocateIdentificator(WiniSections: TWiniSections; const Identificator: string): integer;
var
i, h: integer;
s: string;
begin
result:= -1;
  for i := WiniSections.iStart to WiniSections.iEnd do
      begin
        s:=LocateId(i);
        if uppercase(s) = uppercase(Identificator) then
          begin
            result:= i;
            break;
          end;
      end;
end;


//Function: LoadIniFile
//Carga un archivo de configuración. Si no existe, cuando
//se llame a ReadIniString o WriteIniString se creará.
function LoadIniFile(const FileName: string): DWORD;
begin
  WiniFileName:= FileName;
  Ini:= TStringList.Create;
  if FileExists(FileName) then
    begin
      result:= WINI_FILE_LOADED;
      Ini.LoadFromFile(FileName);
    end else
      result:= WINI_FILE_CRETED;
end;


//Function: ReadStringIdentificator.
//Devuelve el valor de un identificador pasándole como parámetro una línea.
function ReadStringIdentificator(index: integer): string;
var
str: string;
i: integer;
begin
  if index = -1 then exit;
  str:= Ini.Strings[index];
  str:= trim(str);
  i:= Pos('=', str);
  result:= Copy(str, i + 1, length(str));
end;

//Procedure: SetStringValue.
//Asigna un valor a un identificador.
procedure SetStringValue(index: integer; value: string);
var
str, a: string;
i: integer;
begin
  if index = -1 then exit;
  str:= Ini.Strings[index];
  str:= trim(str);
  i:= Pos('=', str);
  a:= Copy(str, 1, i);
  a:= a + value;
  Ini.Strings[index]:= a;
end;


//Function: WriteIniString.
//Función básica para modificar el valor de un identificador, pasándole como parámetros
//su sección, identificador y valor a asignar.
function WriteIniString(const Section: string; const Identificator: string; const Value: string): DWORD;
var
IniSections: TWiniSections;
index: integer;
begin
result:= WINI_WRITE_ERROR_UNKNOWN;
if LocateSection(Section, IniSections) = true then
  begin
     index:=LocateIdentificator(IniSections, Identificator);
     if index < 0 then
      begin
        Ini.Insert(IniSections.iEnd + 1, Identificator + '=' + Value);
        ini.SaveToFile(WiniFileName);
        result:= WINI_WRITE_IDENTIFICATOR_ADDED;
        exit;
      end;
     SetStringValue(index, value);
     Ini.SaveToFile(WiniFileName);
     result:= WINI_WRITE_VALUE_CHANGED;
  end else
    begin
      Ini.Add('[' + Section + ']');
      Ini.Add(Identificator + '=' + Value);
      Ini.SaveToFile(WiniFileName);
      result:= WINI_WRITE_SECTION_ADDED;
    end;
end;


//Function: ReadIniString.
//Función que devuelve el valor de un identificador, pasándole como parámetros
//su sección, identificador y valor por defecto por si no existe el archivo o clave.
function ReadIniString(const Section: string; const Identificator: string; const Default: string): string;
var
IniSections: TWiniSections;
index: integer;
begin
result:= EmptyStr;
if LocateSection(Section, IniSections) = true then
  begin
     index:=LocateIdentificator(IniSections, Identificator);
     if index < 0 then
      begin
        Ini.Insert(IniSections.iEnd + 1, Identificator + '=' + Default);
        ini.SaveToFile(WiniFileName);
        result:= Default;
        exit;
      end;
     result:= ReadStringIdentificator(index);
  end else
    begin
     Ini.Add('[' + Section + ']');
     Ini.Add(Identificator + '=' + Default);
     Ini.SaveToFile(WiniFileName);
     result:= Default;
    end;
end;


//Function: FreeWini
//Función para liberar el archivo de configuración.
function FreeWini: DWORD;
begin
  try
    Ini.SaveToFile(WiniFileName);
    Ini.Free;
    result:= WINI_FREE_OK;
  except
    result:= WINI_FREE_ERROR;
  end;
end;

{End Wini Unit}

//CopyRight 2008 (C) Khronos
//email: tanisperez@gmail.com
//...
end.

En el siguiente enlace viene todo el código fuente junto a un pequeño ejemplo práctico:
http://rapidshare.com/files/167397940/Wini.zip.html

PD: Le puse el acrónimo de Wini (Windows Ini Files) porque me parece bastante simpático y hace referencia a su función

Saludos.

Última edición por Khronos fecha: 25-11-2008 a las 23:36:52.
Responder Con Cita