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;
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(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 (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(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(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(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(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(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(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: DWORD;
begin
try
Ini.SaveToFile(WiniFileName);
Ini.Free;
result:= WINI_FREE_OK;
except
result:= WINI_FREE_ERROR;
end;
end;
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.