|
Antwort |
Wie der Titel bereits besagt, Ini Support ohne IniFiles Unit zu verwenden, komplett auf WinApi Methoden aufgebaut.
Sinn und Zweck: Hauptsächlich gut für kleine NonVcl oder Konsolen Projekte die nicht viel Ini Funktionalität benötigen. Status: Finale Beta Der aktuelle Stand der Dinge:
Delphi-Quellcode:
Anregungen, Kritik, Verbesserungen, alles willkommen, tobt Euch aus und viel Spass
(*
Achtung: Diese Unit nicht in "Verkaufssoftware" verwenden. Nehmt original IniFiles Unit und gut ist. Diese Unit ist gut für kleine NonVcl oder Konsolen Projekte geeignet die keine so umfangreiche Ini abdeckung brauchen. Obwohl ich alles getestet habe, besteht immer die Gefahr das etwas nicht so funktioniert wie vorhergesehen! Für mich ist es ein Forschungsprojekt um zu sehen wie Windows arbeitet und wieviel Bytes man sparen kann. Ziel war es lediglich die Windows Unit einbinden zu müssen um Ini-Support zu ermöglichen. erstellt im Sommer 2020 von KodeZwerg Neuerungen: Alle default Werte verworfen. Umstellung von Class auf Record typ. Code refactored. properties erstellt um die art des aufrufs abzukürzen. SmallestBuild direktive um lediglich strings lesen/schreiben zu können, so kann jeder auf seine gewohnte RTL zurückgreifen. Es sollte alles sauber funktionieren solange der Input passt. Wer sichergehen möchte das alles wie erwartet reibungslos funktioniert, dem Empfehle ich sich auf Read-/WriteString() bei Benutzung zu beschränken und in der Projekt-Unit selbst eine Datenumwandlung vom/zum String-typ einzupflegen. (zBsp ist bei mir ein Boolean entweder '1' oder '0' und nicht 'True' oder 'False' bzw alles was nicht '0' ist, entspricht 'True') (In diesen Zusammenhang ist die direktive SmallestBuild recht nützlich.) Danke an himitsu für den record Vorschlag anstelle einer Klassen-Nutzung! Danke an himitsu für ein ReadString Beispiel ohne mehrere Variablen in Benutzung zu haben! Lizenz: OpenSource ohne ein Lizenzmodell oder Beschränkungen jeglicher Art. Haftung: keine, Benutzung auf Eigene Gefahr. Kurzanleitung: bindet diese Unit ein, gebt einer Variablen in Eurem Projekt als Datentyp TkzIni an. Als Beispiel: var Ini: TkzIni; ab nun kann man über diese variable ini dateien ansprechen und bearbeiten. Als Beispiel: TestString := Ini.ReadString('Pfad:\Dateiname.ini', 'Optionen', 'OptionsName', 'OptionsGrundwert'); je mehr properties man setzt umso kürzer wird der letztendliche aufruf, siehe folgendes Beispiel. so könnte man vorgehen, wenn man mehrere dinge auslesen möchte. Ini.FileName := 'Pfad:\Dateiname.ini'; Ini.Section := 'Optionen'; TestString := Ini.ReadString('OptionsName', 'OptionsGrundwert'); TestInteger := Ini.ReadInteger('IntegerName', 42); *) unit kzIniFiles; {.$DEFINE SmallestBuild} interface type TkzIni = record {$IFNDEF SmallestBuild} private { Properties } FFileName: string; FSection: string; FIdent: string; { Datentypumwandlungshelfer } function _IntToStr(const Value: Integer): string; function _StrToInt(const Value: string): Integer; function _BoolToStr(const Value: Boolean): string; function _StrToBool(const Value: string): Boolean; function _FloatToStr(const Value: Real): string; function _StrToFloat(const Value: string): Real; {$ENDIF SmallestBuild} public { Basis funktionalität, alle anderen methoden nutzen diese intern } function ReadString(const FileName, Section, Ident, Default: string): string; overload; function WriteString(const FileName, Section, Ident, Value: string): Boolean; overload; {$IFNDEF SmallestBuild} { erweiterte Basis methoden, diese methoden nutzen die _helfer } function ReadInteger(const FileName, Section, Ident: string; const Default: Integer): Integer; overload; function WriteInteger(const FileName, Section, Ident: string; const Value: Integer): Boolean; overload; function ReadBoolean(const FileName, Section, Ident: string; const Default: Boolean): Boolean; overload; function WriteBoolean(const FileName, Section, Ident: string; const Value: Boolean): Boolean; overload; function ReadFloat(const FileName, Section, Ident: string; const Default: Real): Real; overload; function WriteFloat(const FileName, Section, Ident: string; const Value: Real): Boolean; overload; { methoden für FileName property } function ReadString(const Section, Ident, Default: string): string; overload; function WriteString(const Section, Ident, Value: string): Boolean; overload; function ReadInteger(const Section, Ident: string; const Default: Integer): Integer; overload; function WriteInteger(const Section, Ident: string; const Value: Integer): Boolean; overload; function ReadBoolean(const Section, Ident: string; const Default: Boolean): Boolean; overload; function WriteBoolean(const Section, Ident: string; const Value: Boolean): Boolean; overload; function ReadFloat(const Section, Ident: string; const Default: Real): Real; overload; function WriteFloat(const Section, Ident: string; const Value: Real): Boolean; overload; { methoden für FileName und Section property } function ReadString(const Ident, Default: string): string; overload; function WriteString(const Ident, Value: string): Boolean; overload; function ReadInteger(const Ident: string; const Default: Integer): Integer; overload; function WriteInteger(const Ident: string; const Value: Integer): Boolean; overload; function ReadBoolean(const Ident: string; const Default: Boolean): Boolean; overload; function WriteBoolean(const Ident: string; const Value: Boolean): Boolean; overload; function ReadFloat(const Ident: string; const Default: Real): Real; overload; function WriteFloat(const Ident: string; const Value: Real): Boolean; overload; { methoden für FileName, Section und Ident property } function ReadString(const Default: string): string; overload; function WriteString(const Value: string): Boolean; overload; function ReadInteger(const Default: Integer): Integer; overload; function WriteInteger(const Value: Integer): Boolean; overload; function ReadBoolean(const Default: Boolean): Boolean; overload; function WriteBoolean(const Value: Boolean): Boolean; overload; function ReadFloat(const Default: Real): Real; overload; function WriteFloat(const Value: Real): Boolean; overload; property FileName: string read FFileName write FFileName; property Section: string read FSection write FSection; property Ident: string read FIdent write FIdent; {$ENDIF SmallestBuild} end; implementation uses Winapi.Windows; {$IFNDEF SmallestBuild} { Datentypumwandlung Integer nach String } function TkzIni._IntToStr(const Value: Integer): string; var s: AnsiString; begin Str(Value, s); Result := string(s); end; { Datentypumwandlung String nach Integer } function TkzIni._StrToInt(const Value: string): Integer; var Code: Integer; begin Val(Value, Result, Code); if (Code <> 0) then Result := 0; end; { Datentypumwandlung Boolean nach String } function TkzIni._BoolToStr(const Value: Boolean): string; begin Result := _IntToStr(Integer(Value)); end; { Datentypumwandlung String nach Boolean } function TkzIni._StrToBool(const Value: string): Boolean; begin Result := (_StrToInt(Value) <> Integer(False)); end; { Datentypumwandlung Float nach String } function TkzIni._FloatToStr(const Value: Real): string; var s: AnsiString; begin Str(Value, s); Result := string(s); end; { Datentypumwandlung String nach Float } function TkzIni._StrToFloat(const Value: string): Real; var Code: Integer; begin Val(Value, Result, Code); if (Code <> 0) then Result := 0.0; end; {$ENDIF SmallestBuild} { Lese String aus Filname Datei } { alle leseoperationen führen hier hin } function TkzIni.ReadString(const FileName, Section, Ident, Default: string): string; begin try SetLength(Result, 1024); SetLength(Result, GetPrivateProfileString(PChar(Section), PChar(Ident), PChar(Default), PChar(Result), Length(Result) + 1, PChar(FileName))); except Result := Default; end; end; { Schreibe String in Filname Datei } { alle schreiboperationen führen hier hin } function TkzIni.WriteString(const FileName, Section, Ident, Value: string): Boolean; begin try Result := WritePrivateProfileString(PChar(Section), PChar(Ident), PChar(Value), PChar(FileName)); except Result := False; end; end; {$IFNDEF SmallestBuild} { Lese Integer aus Filname Datei } function TkzIni.ReadInteger(const FileName, Section, Ident: string; const Default: Integer): Integer; begin try Result := _StrToInt(ReadString(FileName, Section, Ident, _IntToStr(Default))); except Result := Default; end; end; { Schreibe Integer in Filname Datei } function TkzIni.WriteInteger(const FileName, Section, Ident: string; const Value: Integer): Boolean; begin try Result := WriteString(FileName, Section, Ident, _IntToStr(Value)); except Result := False; end; end; { Lese Boolean aus Filname Datei } function TkzIni.ReadBoolean(const FileName, Section, Ident: string; const Default: Boolean): Boolean; begin try Result := _StrToBool(ReadString(FileName, Section, Ident, _BoolToStr(Default))); except Result := Default; end; end; { Schreibe Boolean in Filname Datei } function TkzIni.WriteBoolean(const FileName, Section, Ident: string; const Value: Boolean): Boolean; begin try Result := WriteString(FileName, Section, Ident, _BoolToStr(Value)); except Result := False; end; end; { Lese Float aus Filname Datei } function TkzIni.ReadFloat(const FileName, Section, Ident: string; const Default: Real): Real; begin try Result := _StrToFloat(ReadString(FileName, Section, Ident, _FloatToStr(Default))); except Result := Default; end; end; { Schreibe Float in Filname Datei } function TkzIni.WriteFloat(const FileName, Section, Ident: string; const Value: Real): Boolean; begin try Result := WriteString(FileName, Section, Ident, _FloatToStr(Value)); except Result := False; end; end; { Lese String aus FFilname Datei } function TkzIni.ReadString(const Section, Ident, Default: string): string; begin try Result := ReadString(FFileName, Section, Ident, Default); except Result := Default; end; end; { Schreibe String in FFilname Datei } function TkzIni.WriteString(const Section, Ident, Value: string): Boolean; begin try Result := WriteString(FFileName, Section, Ident, Value); except Result := False; end; end; { Lese Integer aus FFilname Datei } function TkzIni.ReadInteger(const Section, Ident: string; const Default: Integer): Integer; begin try Result := _StrToInt(ReadString(Section, Ident, _IntToStr(Default))); except Result := Default; end; end; { Schreibe Integer in FFilname Datei } function TkzIni.WriteInteger(const Section, Ident: string; const Value: Integer): Boolean; begin try Result := WriteString(Section, Ident, _IntToStr(Value)); except Result := False; end; end; { Lese Boolean aus FFilname Datei } function TkzIni.ReadBoolean(const Section, Ident: string; const Default: Boolean): Boolean; begin try Result := _StrToBool(ReadString(Section, Ident, _BoolToStr(Default))); except Result := Default; end; end; { Schreibe Boolean in FFilname Datei } function TkzIni.WriteBoolean(const Section, Ident: string; const Value: Boolean): Boolean; begin try Result := WriteString(Section, Ident, _BoolToStr(Value)); except Result := False; end; end; { Lese Float aus FFilname Datei } function TkzIni.ReadFloat(const Section, Ident: string; const Default: Real): Real; begin try Result := _StrToFloat(ReadString(Section, Ident, _FloatToStr(Default))); except Result := Default; end; end; { Schreibe Float in FFilname Datei } function TkzIni.WriteFloat(const Section, Ident: string; const Value: Real): Boolean; begin try Result := WriteString(Section, Ident, _FloatToStr(Value)); except Result := False; end; end; { Lese String aus FFilname Datei } function TkzIni.ReadString(const Ident, Default: string): string; begin try Result := ReadString(FFileName, FSection, Ident, Default); except Result := Default; end; end; { Schreibe String in FFilname Datei } function TkzIni.WriteString(const Ident, Value: string): Boolean; begin try Result := WriteString(FFileName, FSection, Ident, Value); except Result := False; end; end; { Lese Integer aus FFilname Datei } function TkzIni.ReadInteger(const Ident: string; const Default: Integer): Integer; begin try Result := _StrToInt(ReadString(Ident, _IntToStr(Default))); except Result := Default; end; end; { Schreibe Integer in FFilname Datei } function TkzIni.WriteInteger(const Ident: string; const Value: Integer): Boolean; begin try Result := WriteString(Ident, _IntToStr(Value)); except Result := False; end; end; { Lese Boolean aus FFilname Datei } function TkzIni.ReadBoolean(const Ident: string; const Default: Boolean): Boolean; begin try Result := _StrToBool(ReadString(Ident, _BoolToStr(Default))); except Result := Default; end; end; { Schreibe Boolean in FFilname Datei } function TkzIni.WriteBoolean(const Ident: string; const Value: Boolean): Boolean; begin try Result := WriteString(Ident, _BoolToStr(Value)); except Result := False; end; end; { Lese Float aus FFilname Datei } function TkzIni.ReadFloat(const Ident: string; const Default: Real): Real; begin try Result := _StrToFloat(ReadString(Ident, _FloatToStr(Default))); except Result := Default; end; end; { Schreibe Float in FFilname Datei } function TkzIni.WriteFloat(const Ident: string; const Value: Real): Boolean; begin try Result := WriteString(Ident, _FloatToStr(Value)); except Result := False; end; end; { Lese String aus FFilname Datei } function TkzIni.ReadString(const Default: string): string; begin try Result := ReadString(FFileName, FSection, FIdent, Default); except Result := Default; end; end; { Schreibe String in FFilname Datei } function TkzIni.WriteString(const Value: string): Boolean; begin try Result := WriteString(FFileName, FSection, FIdent, Value); except Result := False; end; end; { Lese Integer aus FFilname Datei } function TkzIni.ReadInteger(const Default: Integer): Integer; begin try Result := _StrToInt(ReadString(_IntToStr(Default))); except Result := Default; end; end; { Schreibe Integer in FFilname Datei } function TkzIni.WriteInteger(const Value: Integer): Boolean; begin try Result := WriteString(_IntToStr(Value)); except Result := False; end; end; { Lese Boolean aus FFilname Datei } function TkzIni.ReadBoolean(const Default: Boolean): Boolean; begin try Result := _StrToBool(ReadString(_BoolToStr(Default))); except Result := Default; end; end; { Schreibe Boolean in FFilname Datei } function TkzIni.WriteBoolean(const Value: Boolean): Boolean; begin try Result := WriteString(_BoolToStr(Value)); except Result := False; end; end; { Lese Float aus FFilname Datei } function TkzIni.ReadFloat(const Default: Real): Real; begin try Result := _StrToFloat(ReadString(_FloatToStr(Default))); except Result := Default; end; end; { Schreibe Float in FFilname Datei } function TkzIni.WriteFloat(const Value: Real): Boolean; begin try Result := WriteString(_FloatToStr(Value)); except Result := False; end; end; {$ENDIF SmallestBuild} end.
Gruß vom KodeZwerg
Geändert von KodeZwerg ( 2. Sep 2020 um 11:52 Uhr) |
Delphi 11 Alexandria |
#11
zumindest geh ich kurz auf diesen Punkt ein:
Warum gibt ReadInteger einen Cardinal zurück?
Danke für den Record Vorschlag! Wie gesagt, das ist gestern Nacht innerhalb von ein paar Minuten nur per Notepad und Windows SDK entstanden. Etwaige Fehler oder Prüfung ob Code überhaupt ausführbar ist steht mir noch bevor. |
Zitat |
Delphi 10.4 Sydney |
#12
Etwaige Fehler oder Prüfung ob Code überhaupt ausführbar ist steht mir noch bevor.
Daniel R. Wolf
|
Zitat |
Delphi 10.4 Sydney |
#13
Immerhin kompiliert das (XE 10.2).
Das Destroy braucht ein override; anstatt ein overload; ! |
Zitat |
Delphi 11 Alexandria |
#14
Dann muss die Frage erlaubt sein, warum Du ihn in diesem Zustand überhaupt veröffentlichst ... ?
Zitat:
Status: Alpha (nur per Notepad erstellt, noch ungetestet)
Hier stelle ich Euch schonmal meine Grundidee vor Ich sammel auf diese Weise eindrücke bzw verbessere alles nach Kritik oder stampfe Projekt ein. himitsu's record zBsp = mega! Darauf bin ich Nachts nicht gekommen. Cool das es kompiliert @TiGü und Danke für's durchlaufen lassen! Klar Override nicht Overload *schäm* |
Zitat |
Delphi 11 Alexandria |
#15
Das
Code:
funktioniert in Unicode-Zeiten doch nicht mehr für die Umlaute?
case s[i] of
'A'..'Z','Ä','Ö','Ü': Result[i] := CHR(Byte(s[i]) + 32); |
Zitat |
Delphi 11 Alexandria |
#16
@TigerLilly: die kleinen _helfer fliegen zu morgen raus. alles wird intern auf string umgestellt (integer bool etc), leichtere Handhabung und readinteger kann dann auch integer returnen
|
Zitat |
Delphi 12 Athens |
#17
Bin ich jetzt der Einzige der mal hinterfragt wie Kompatibel das Ganze ist ?
https://stackoverflow.com/questions/...m-kernel32-dll Das ist doch meiner Meinung nach für Win-10 gar nicht mehr aktuell, oder irre ich mich da ? |
Zitat |
Delphi 12 Athens |
#18
Dort war das Problem bei UWP und da bist die mit Delphi sowieso im Arsch, denn Embarcadero weigert sich schon seit 8 Jahren hartnäckig einen Compiler für WinRT/UWP zu bauen.
Das ist leider die einzige INI-API, also geht es nicht anders. Und dieser Hinweis steht schon seit 25 Jahren dort ... glaub mir, das werden die nicht so schnell ausbauen , auch wenn Microsoft will, dass wir von INI auf die Registry umstellen, dabei nutzen die selbst massenhaft INIs, überall im System. Nicht die API ist als deprecated eingestuft, sondern der Speicherort.
Zitat:
Weil das die WinApi so macht. Sie returned einen Cardinal/UINT.
Ich hatte mir auch schon eine kleine INI-Klasse gebastelt, die z.B. auch Multiline-Values erlaubt, so wie es andere INI-Libs, z.B. in einigen Games oder für Linux auch anbieten. Geändert von himitsu (27. Aug 2020 um 13:10 Uhr) |
Zitat |
venice2
|
#19
Zitat:
für den produktiven Einsatz wird es dann vielleicht doch spannend, ob das selbst geschriebene FileExists auch auf Netzwerkpfaden funktioniert und derlei mehr.
1.Ich prüfe erst einmal ob es sich um einen Netzwerkpfad handelt. Dazu vergleiche ich auf "\\" im Pfad. 2.Anschließend prüfe ich ob es sich um ein Remote Laufwerk handelt über GetDriveType = DRIVE_REMOTE 3. Dann verwende ich WNetGetConnection mit dem Flag ERROR_MORE_DATA falls der Buffer zu schmal ist alloziere ich einen entsprechenden der dann passt. Über WNetGetConnection erhält man den UNC Pfad von einem gemappten Laufwerk. (Nur zur Vervollständigung) 4.Gibt der nächst Aufruf von WNetGetConnection NO_ERROR zurück dann wurde der Pfad gefunden. 5.Das alles garantiert mir aber nicht das ich die Datei auch lesen kann. Also muss ich einen ping absetzen der mir garantiert das der Port auch geöffnet ist um die Datei lesen zu können. "IsPortAvailable" 6. Wenn dann der Pfad und die Datei existiert "PathFileExists" ist die Rückgabe true. Wo ist nun das Problem eine Function gleich "FileExists" für ein Netzwerkpfad zu erstellen? Und ja habe nichts neu erfunden wie schon gesagt ist alles vorhanden. Habe jetzt nur mal einen möglichen Vorgang beschrieben Code gibt es nicht. Jeder nutzt halt eine für sich angepasste variante von FileExists die meisten die Vorgekaute. Ob es jetzt mit Portprobe Probleme mit der Firewall oder anderen Sicherheitssuiten gibt kann ich nicht garantieren muss man halt testen. Er könnte nun sein _FileExists entsprechend meiner Vorgehensweise anpassen und schon klappt das mit deinen Netzwerkpfaden. Nachtrag: Ping ist aber kein Garant das der Server/Client auch wirklich hochgefahren ist. Deswegen nutze ich eine Portprobe und schau ob ein bestimmter Port vom Server/Client erreichbar ist. Ist der Port erreichbar ist der Server auch hochgefahren und dann sollte auch der Ordner\Datei erreichbar sein. Geändert von venice2 (28. Aug 2020 um 21:17 Uhr) |
Zitat |
Delphi 12 Athens |
#20
Um zu Testen ob ein Zugriff nach allen Vortests wirklich machbar ist, z.B. bei mobilen Platformen und deren Verzeichnissen,
Lasse ich auch schon Mal gern eine Temporäre Datei erzeugen und lösche die gleich wieder. Wenn man ohne Exceptions durchkommt ist Alles IO, und ich kann den echten Zugriff machen. Ist suboptimal, erfüllt aber seinen Zweck wenn alle möglichen Unwägbarkeiten den Zugriff behindern. |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |