Entwickler-Ecke

Open Source Units - SJ Config Utils 1.0 RC 3


jaenicke - Di 19.05.09 16:39
Titel: SJ Config Utils 1.0 RC 3
Hallo!

Diese Unit stellt eine Klasse zur automatischen Verwaltung der Einstellungen zur Verfügung. Um diese in einem eigenen Programm zu verwenden, bindet man die Unit ein und leitet eine eigene Einstellungsklasse von TAppConfigManager ab. Diese Klasse muss dann bestimmte Methoden implementieren und bekommt die notwendigen Objekte zum Auslesen der Einstellungen geliefert.
Mehr dazu im zweiten Teil unter Implementierung im eigenen Programm [http://www.delphi-forum.de/viewtopic.php?p=564401#564401].

Es gibt ein Tool [http://www.delphi-forum.de/viewtopic.php?p=580893], das automatisch die Änderungen am Delphiprojekt vornimmt, so dass kaum noch manuelle Anpassungen notwendig sind. Dieses ist im Download enthalten.

Eine Demo ist mit im Download enthalten. Der Wizard davon sieht so aus:
[url=http://www.sj-berlin.de/service/df/screenshots/config/sjconfigutils_wizard.png]user defined image[/url]

Ein Forum zum Support und mit weiteren Informationen entsteht hier:
http://sjberlin.de/forum/viewforum.php?f=24

Features:
Lizenz:
MPL 1.1 oder GPL 2.0 oder LGPL 2.1

Installation:
Die Units müssen entweder in den Bibliothekspfad aufgenommen oder dem Projekt hinzugefügt werden, damit die Units über die uses-Klausel eingebunden werden kann.
Zur Verwendung siehe die Details im zweiten Teil:
http://www.delphi-forum.de/viewtopic.php?p=564401#564401

Unterstützte Delphiversionen:
Delphi 6, 7, 2006, 2007 und 2009
(in Delphi 7 und früher fehlt ggf. die XML-Unterstützung, daher muss in Source\SJConfigUtils.inc der Schalter für XML-Unterstützung deaktiviert werden)

Unterstützte Windowsversionen:
Windows 2000, XP, Vista und 7

Weitere Planung:Bekannte Probleme:
Einen FAQ Eintrag mit weiteren Informationen zu den Hintergründen findet ihr hier:
http://www.delphi-library.de/viewtopic.php?p=541637

Ich habe die Unit auch hier vorgestellt:
http://forum.delphi-treff.de/showthread.php?t=26681 [http://forum.delphi-treff.de/showthread.php?t=26681]
http://www.delphipraxis.net/post1042717.html [http://www.delphipraxis.net/post1042717.html]

Ich habe mal ein kleines Demovideo gemacht zur besseren Illustration des Integrationstools: ;-)
http://www.sjberlin.de/service/videos/config_utils_demo.wmv (ggf. vorher speichern)
Und für den IE als Webseite: http://www.sjberlin.de/service/videos/config_utils_demo.html

Schönen Gruß,
Sebastian


jaenicke - Fr 29.05.09 04:08

Teil 2: Implementierung im eigenen Programm

Wie ich bereits gesagt habe muss die eigene Einstellungsklasse von TAppConfigManager abgeleitet werden. Wenn bereits eine solche Klasse existiert, kann diese einfach entsprechend ergänzt werden. So habe ich es bei meinen Projekten auch gemacht.
Dann müssen ein paar Methoden überschrieben bzw. implementiert werden. Insgesamt sieht das dann so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
uses
  XMLIntf, IniFiles, Registry, SJConfigUtils, ...;

type
  TAppConfig = class(TAppConfigManager)
  protected
    procedure LoadFromStream(Data: TStream); override;
    procedure SaveToXml(Ini: IXMLDocument); override;
    procedure LoadFromINI(Ini: TCustomIniFile); override;
    procedure LoadFromRegistry(Reg: TRegistry; ParentPath: String); override;

    procedure SaveToStream(Data: TStream); override;
    procedure LoadFromXml(Ini: IXMLDocument); override;
    procedure SaveToINI(Ini: TCustomIniFile); override;
    procedure SaveToRegistry(Reg: TRegistry; ParentPath: String); override;

    procedure RunConfigWizard; override;
    procedure ApplyStandardSettings; override;
    procedure GetProgramInfo(var Author, ProductName, ProductVersion: string); override;
  end;

implementation

uses
  ConfigWizard;

{ TAppConfig }

// Allgemeine Aufgaben

procedure TAppConfig.RunConfigWizard;
begin
  frmConfigWizard := TfrmConfigWizard.Create(nil);
  frmConfigWizard.ShowModal(Self);
end;

procedure TAppConfig.ApplyStandardSettings;
begin
  fUserName := 'Standardname'
end;

procedure TAppConfig.GetProgramInfo(var Author, ProductName,
  ProductVersion: string);
begin
  Author := 'Sebastian Jänicke';
  ProductName := 'SJ Config Utils Demo';
  ProductVersion := '1.0';
end;

...
Bei RunConfigWizard muss ein eigener Einstellungswizard angezeigt werden, der den Benutzer auch nach dem Ort für die Einstellungen fragen sollte. Ihr könnt natürlich den der Demo übernehmen und anpassen.

Für das Auslesen und Speichern der Einstellungen gibt es ReadString, WriteString, und so weiter. Das sieht dann so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TAppConfig.LoadFromXml(Ini: IXMLDocument);
begin
  if AccessManager.InitReadLocation('Userinfo', sIniSectionOpenError) then
  begin
    fUserName := AccessManager.ReadString('Username', sIniValueNotFound);
  end;
end;

...
Dabei wird mit InitReadLocation ein Knoten einer XML-Datei, ein Schlüssel in der Registry oder eine Sektion einer INI geöffnet und dann darin die Werte gelesen.

Eine andere Möglichkeit ist, die übergebenen Objekte direkt zu verwenden um die XML-Datei usw. direkt auszulesen oder zu schreiben.

Welche Speicherarten verfügbar sind und welche Methoden dementsprechend implementiert werden müssen, wird in der Unit SJConfigUtils ganz oben per Compilerdirektive festgelegt.

Eine komplette Implementierung findet ihr in der mitgelieferten Demo.


jaenicke - Fr 29.05.09 16:19

Ich habe jetzt eine aktualisierte Version hochgeladen, die ich mit Delphi 6, 7, 2006, 2007 und 2009 erfolgreich getestet habe. Zudem habe ich einen Flüchtigkeitsfehler beim Streamformat behoben, der dazu geführt hatte, dass es gar nicht funktionierte.

Unter Delphi 6 und 7 muss einfach der Schalter für die XML-Unterstützung deaktiviert werden, die Formulare der Demo einmal alle geöffnet und die Fehlermeldungen ignoriert werden. Dann sollte es laufen.


jaenicke - Mi 03.06.09 14:50

Ich habe einmal eine neue Betaversion hochgeladen.
Neuerungen:


jaenicke - Di 23.06.09 08:46

Es gibt eine neue Version. Jetzt kann man die Einstellungen auch an die Exe anhängen. Dafür habe ich (auf einen Vorschlag in) mein Projekt SJExeDataStream [http://www.delphi-forum.de/viewtopic.php?t=89659] in dieses hier integriert.

Diese Möglichkeit könnte insbesondere für die schnelle portable Weitergabe von Tools sehr nützlich sein.

Die neue Version habe ich eingehender getestet und in einige Projekte eingebaut. Da mir keine Fehler aufgefallen sind und es auch keine Meldungen mehr zu Fehlern gab, gebe ich die Version als Release Candidate heraus.


Sinspin - Di 23.06.09 11:34

Gute Idee. Ich habe mir sowas mal selber geschrieben. Allerdings nur XML basiert und mit einem sich automatisch generierenden Konfigurationsdialog wenn die Definition für die Konfiguration schon vorhanden ist.
Ich habe mich für XML entschieden um eine echte Baumstruktur für die Einstellungen hinzubekommen, also mit Gruppen und Untergruppen auf N Ebenen.
Und mit der Möglichkeit einfach Position und Größe von Fenstern speichern und laden zu können. Über das Konfigurationprogramm können die einzelnen Knoten und Datenpunkte erstellt werden. Es lassen sich Datentyp und Bereich der Eingabe festlegen die dann im Programm beachtet werden müssen. Es gibt einen Quelltext Generator mit dem die Grundkonfiguration generiert werden kann um die Datei jederzeit neu erstellen zu können. Die Datei kann durch eine Checksumme vor unerwünschten Änderungen geschützt werden, besser gesagt im Programm lässt sich so ermitteln ob die Datei mit einem externen Editor geändert wurde.

In Delphi 7 ist XML aber mit im Lieferumfang enthalten. In Delphi 6 habe ich es mir von Hand nachgerüstet, also aus einem 7ner kopiert als ich noch teiweise mit Delphi 6 gearbeitet habe. Und wenn man das Delphi eigene XML nicht verwenden will gibt es immernoch MSXML.


jaenicke - Di 23.06.09 11:50

user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe mich für XML entschieden um eine echte Baumstruktur für die Einstellungen hinzubekommen, also mit Gruppen und Untergruppen auf N Ebenen.
Da hatte ich auch überlegt, ob ich da noch mehr zur Vereinfachung einbauen sollte, dann habe ich das aber nicht gemacht. Denn wer das so braucht, kann ja selbst mit dem XML-Objekt arbeiten.

Ach ja: Was ich noch plane ist die integrierte Unterstützung zum Speichern von Listen, damit man die nicht selbst zeilenweise speichern und auslesen muss.

user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
Es gibt einen Quelltext Generator mit dem die Grundkonfiguration generiert werden kann um die Datei jederzeit neu erstellen zu können.
Sowas plane ich als Assistent ja auch bzw. bin dabei den zu implementieren. Genauer gesagt plane ich einen in Delphi integrierten Experten, den man installieren kann, und alternativ (für Turbo Delphi Explorer z.B.) ein externes Tool (oder ich mache es über einen DLL Experten).

user profile iconSinspin hat folgendes geschrieben Zum zitierten Posting springen:
In Delphi 7 ist XML aber mit im Lieferumfang enthalten.
Stimmt ich sehs. Ich gehe beim Testen immer von der Personal Edition von D7 aus, und da ist es nicht dabei.


jaenicke - So 11.10.09 10:40

Es gibt endlich eine neue Version.Wenn damit jetzt keine unterwarteten Probleme auftreten, wird diese Version dann die Final sobald das auch für das Zusatztool gilt und damit die Entwicklung zunächst abgeschlossen.

// EDIT:
Quickfix für XP, dort funktioniert leider eine API-Funktion anders als ab Vista. Jetzt geht es auch unter XP.


jaenicke - So 25.10.09 14:18

Es gibt eine neue Version inkl. voll funktionsfähiger und getesteter Version des Integrationstools. Sowohl die Config Utils als auch das Tool sind jetzt soweit fertig. Sofern nicht noch Probleme mit dem RC bei euch auftreten, die noch behoben werden müssen, schließe ich die Entwicklung dieser Version dann ab.

Also: bitte fleißig testen. :mrgreen:


Terra23 - Mo 25.03.13 19:27

Hi jaenicke!

Inzwischen habe ich mich auch mal an dein Programm gewagt. Ich hab im Prinzip zum Üben erstmal das machen wollen, was du in deinem Video gemacht hast.

Leider tauchen bei mir einige Fehler auf, die meine Kenntnisse übersteigen.

Ich habe sie dir mal im Anhang beigefügt.

Wenn ich den Fehler, der in Error1.jpg gezeigt wird, wegklicke, kommt die gleiche Meldung noch einige Male, aber mit anderen Gründen:


- pnl.Top.BevelEdges / BevelEdges
- pnl.Top.BevelKind / BevelKind
- imgSetup.ExplicitLeft / ExplicitLeft
- tsStartup.ExplicitLeft / ExplicitLeft
- tsStratup.ExplicitTop / ExplicitTop
- ...
- fraAutoNaviButtons.ExplicitLeft / ExplicitLeft
- ...

Kannst du mir helfen?


platzwart - Mo 25.03.13 20:13

Soweit ich das erkenne, steht in der Fehlermeldung "Operator auf diesen Typ nicht anwendbar: Inkompatible Typen 'Boolean' und 'Integer'". In der For-Schleife kannst du keine Variable vom Typ "Boolean" nutzen. Kannst du die Screenshots in höherer Auflösung bereitstellen?


Terra23 - Mo 25.03.13 20:23

Ich hab das mal auf meinen Webspace geladen.

Wie gesagt: Ich habe nix gemacht; nur der Anweisung im Tutorial gefolgt. ;)

Klick für Screen [http://home.arcor.de/Terra23/Error_gross.jpg]

Gruß,

Terra


platzwart - Mo 25.03.13 23:08

Vermutung: Funktioniert "for in" schon unter Delphi 7???

Probiere mal manuell durch ConfigGroupboxItems zu iterieren.


jaenicke - Mo 25.03.13 23:20

Du hast leider nur Delphi 7, die Unit selbst sollte zwar mit Delphi 7 laufen, aber in den Beispielen habe ich da wohl nicht drauf geachtet... auch weil ich die neuen Features der aktuellen Delphiversionen auch gar nicht mehr missen möchte. ;-)

Du musst aus der for..in Schleife eine normale Schleife machen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  i: Integer;
begin
  for i := 0 to ConfigGroupBoxItems.Count - 1 do
    rgSettingsLocation.Items.Add(ConfigGroupBoxItemNames[ConfigGroupBoxItems[i]]);
  ...
Analog die zweite Schleife.


Terra23 - Mo 25.03.13 23:28

Ich werde es morgen mal probieren. Was ist mit dem anderen "Bug"? Klick [http://home.arcor.de/Terra23/Error3.jpg]...


jaenicke - Di 26.03.13 09:09

Das lässt sich leider nicht ändern. das sind Eigenschaften für neue Features von Delphi. Du kannst die Fehler aber einfach ignorieren, dann werden diese Eigenschaften gelöscht und alles funktioniert.


gerd8888 - Do 25.04.13 21:18

Die portable Installation ist mir persoenlich am liebsten.
Die registry wird irgendwann mal aussterben vermute ich stark.
Aus dem einfachen Grund: es muss schnell und einfach gehen.
Den registry Schluessel suchen um ihn spaeter löschen zu müssen, weil man dann erst wieder die software
installieren kann, hat mich schon immer genervt.


jaenicke - Do 25.04.13 22:46

Ich selbst benutze im Gegenteil immer die Registry. ;-)
Manuell darin ändern sollte allerdings nie ein User machen müssen, aber ich sehe dafür auch keinen Grund, dafür gibt es ja Setups oder die Software kümmert sich selbst darum.

Portabel ist für USB Sticks sicher gut, aber auf einem normal installierten System zumindest für mich keine brauchbare Lösung. Wie soll ich da denn eine ordentliche Datensicherung hinbekommen?

Ich kann so wie es im Moment eingerichtet ist jederzeit das komplette System sichern und wiederherstellen ohne dabei irgendwelche eigenen Daten oder Einstellungen zu beeinträchtigen. Die liegen nämlich auf einer anderen Partition. Wie sollte das gehen, wenn die wie damals bei Windows 9x mitten zwischen den Programmen liegen?

Sollte ich irgendwann die Zeit finden will ich die Config Utils noch einmal komplett überarbeiten, insbesondere für neue Delphiversionen, denn mit den neuen Features ließe sich einiges sehr viel einfacher und schöner umsetzen...