Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Proyecto Wini (https://www.clubdelphi.com/foros/showthread.php?t=61884)

Khronos 25-11-2008 23:28:24

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 :D

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 :D

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 :D

Saludos.

BlueSteel 26-11-2008 17:05:00

Cita:

Empezado por Khronos (Mensaje 327947)
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 :D

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 :D

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

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

Saludos.

Hola Khronos...

se ve interesante ... podrias subirlo tambien a la sección de Trucos... creo que allí vendria muy bien...

Salu2:p:D

Khronos 26-11-2008 17:11:25

Muchas gracias BlueSteel, ahora lo pongo en la sección trucos ;)

Saludos.

felipe88 26-11-2008 17:43:20

Práctico :)

Además pienso que es un buen ejemplo para aquellos (me incluyo :p) que apenas empezamos a trabajar con archivos *.ini

raich 26-11-2008 23:41:07

Lo probe y funciona excelente
 
Felicitaciones

marcoszorrilla 27-11-2008 06:58:28

Muchas gracias por tu aportación.


Un Saludo.

Khronos 29-11-2008 01:09:17

Muchas gracias, haber que opinan los grandes maestros del club :D

En una futura versión se podría hacer sin utilizar la clase TStringList para optimizarlo, por ejemplo: usando AssignFile, FileClose, Reset, FileSize... pero eso ya lo veo mucho más complicado :p

Saludos.

darkone2k4 19-03-2009 22:14:20

excelente.. muchas gracias.....;);)


Podrías volver a resubir el archivo wini.zip???, xq desde rapidshare no se puede descargar :(:(

Khronos 21-03-2009 15:49:51

Lo siento gmail me daba un problema con el correo que me facilitastes por mp. Lo subí a rapidshare de nuevo.

http://rapidshare.com/files/211821715/wini.rar.html

Saludos.

darkone2k4 21-03-2009 22:31:49

muchas gracias....

te lo agradezco.....

harimuya 25-02-2011 15:54:36

Es posible que me envien el archivo, ya que no esta disponible actualmente.

Gracias.

Fakedo0r 06-05-2012 03:47:56

Hola, gracias por tu codigo. Por cierto, desconocia ese error que con cuentas limitadas se producen errores. En todo caso, aqui te dejo una alternativa mia que no me ha dado ningun error hasta hora.

Código Delphi [-]
//******************************************************************************
//* UNIT:         UNT_GetWriteINI
//* AUTOR:        Fakedo0r
//* FECHA:        14.04.2012
//* CORREO:       Luvel88@gmail.com
//* BLOG:         Sub-Soul.blogspot.com
//* DESCRIPCION:  Permite Leer / Escribir ficheros tipo *.INI
//* USO:          GetINI('C:\Config.ini', 'Opciones', 'Puerto', '');
//*               WriteINI('C:\Config.ini', 'Opciones', 'Puerto', '5005');
//******************************************************************************
unit UNT_GetWriteINI;
//******************************************************************************
//DECLARACION DE LIBRERIAS / CLASES
//******************************************************************************
interface

uses
  Winapi.Windows, System.SysUtils;
//******************************************************************************
//DECLARACION DE FUNCIONES / PROCEDIMIENTOS
//******************************************************************************
function GetINI(sPath: String; sName: String; sKeyName: String; sDefault: String): String;
function WriteINI(sPath: String; sName: String; sKeyName: String; sValor: String): Bool;
//******************************************************************************
implementation
//******************************************************************************
//<--- LEE FICHEROS *.INI --->
//******************************************************************************
function GetINI(sPath: String; sName: String; sKeyName: String; sDefault: String): String;
var
  dwFile:   DWORD;
  sBuffer:  String;
  iSize:    Integer;
begin
  iSize := 0;
  dwFile := CreateFile(PChar(sPath), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  iSize := GetFileSize(dwFile, 0);

  if iSize = - 1 then exit;

  SetLength(sBuffer, iSize);
  iSize := GetPrivateProfileString(PChar(sName), PChar(sKeyName), PChar(sDefault), PChar(sBuffer), iSize, PChar(sPath));

  Result := Copy(sBuffer, 1, iSize);
end;
//******************************************************************************
//<--- ESCRIBE FICHEROS *.INI --->
//******************************************************************************
function WriteINI(sPath: String; sName: String; sKeyName: String; sValor: String): Bool;
begin
  if WritePrivateProfileString(PChar(sName), PChar(sKeyName), PChar(sValor), PChar(sPath)) = True then
    Result := True
  Else
    Result := False;
end;

end.

Saludo.

Jose Roman 07-01-2015 19:02:31

Hola Khronos,

Hoy vi tu tema, me gustaria saber si puedes subir de nuevo el enlace ya que no se encuentra disponible. Gracias


La franja horaria es GMT +2. Ahora son las 18:08:40.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi